diff --git a/cov/cmdline/check.c.func-sort-c.html b/cov/cmdline/check.c.func-sort-c.html index 5cbc315a..9d707518 100644 --- a/cov/cmdline/check.c.func-sort-c.html +++ b/cov/cmdline/check.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 9 @@ -69,19 +69,19 @@ repair - 869090 + 869089 blockcmp - 468340 + 468172 repair_step - 260919 + 260805 is_hash_matching - 209415 + 209449 is_parity_matching diff --git a/cov/cmdline/check.c.func.html b/cov/cmdline/check.c.func.html index d4f4a28c..9544066b 100644 --- a/cov/cmdline/check.c.func.html +++ b/cov/cmdline/check.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 9 @@ -65,7 +65,7 @@ blockcmp - 468340 + 468172 file_post @@ -73,7 +73,7 @@ is_hash_matching - 209415 + 209449 is_parity_matching @@ -81,11 +81,11 @@ repair - 869090 + 869089 repair_step - 260919 + 260805 state_check diff --git a/cov/cmdline/check.c.gcov.html b/cov/cmdline/check.c.gcov.html index 74a027d8..d2e357c6 100644 --- a/cov/cmdline/check.c.gcov.html +++ b/cov/cmdline/check.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 9 @@ -129,64 +129,64 @@ 67 : * Check if a block hash matches the specified buffer. 68 : * Return ==0 if equal 69 : */ - 70 468340 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero) + 70 468172 : static int blockcmp(struct snapraid_state* state, int rehash, struct snapraid_block* block, unsigned pos_size, unsigned char* buffer, unsigned char* buffer_zero) 71 : { 72 : unsigned char hash[HASH_SIZE]; 73 : 74 : /* now compute the hash of the valid part */ - 75 468340 : if (rehash) { - 76 22269 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size); + 75 468172 : if (rehash) { + 76 22270 : memhash(state->prevhash, state->prevhashseed, hash, buffer, pos_size); 77 : } else { - 78 446071 : memhash(state->hash, state->hashseed, hash, buffer, pos_size); + 78 445902 : memhash(state->hash, state->hashseed, hash, buffer, pos_size); 79 : } 80 : 81 : /* compare the hash */ - 82 468340 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { - 83 13881 : return -1; + 82 468172 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { + 83 13872 : return -1; 84 : } 85 : 86 : /* compare to the end of the block */ - 87 454459 : if (pos_size < state->block_size) { - 88 187794 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) { - 89 21 : return -1; + 87 454300 : if (pos_size < state->block_size) { + 88 187749 : if (memcmp(buffer + pos_size, buffer_zero + pos_size, state->block_size - pos_size) != 0) { + 89 24 : return -1; 90 : } 91 : } 92 : - 93 454438 : return 0; + 93 454276 : return 0; 94 : } 95 : 96 : /** 97 : * Check if the hash of all the failed block we are expecting to recover are now matching. 98 : */ - 99 209415 : static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void* buffer_zero) + 99 209449 : static int is_hash_matching(struct snapraid_state* state, int rehash, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void* buffer_zero) 100 : { 101 : unsigned j; 102 : int hash_checked; 103 : - 104 209415 : hash_checked = 0; /* keep track if we check at least one block */ + 104 209449 : hash_checked = 0; /* keep track if we check at least one block */ 105 : 106 : /* check if the recovered blocks are OK */ - 107 668375 : for (j = 0; j < failed_count; ++j) { + 107 668247 : for (j = 0; j < failed_count; ++j) { 108 : /* if we are expected to recover this block */ - 109 472862 : if (!failed[failed_map[j]].is_outofdate + 109 472694 : if (!failed[failed_map[j]].is_outofdate 110 : /* if the block has a hash to check */ - 111 468340 : && block_has_updated_hash(failed[failed_map[j]].block) + 111 468172 : && block_has_updated_hash(failed[failed_map[j]].block) 112 : ) { 113 : /* if a hash doesn't match, fail the check */ - 114 468340 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size); - 115 468340 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) { - 116 13902 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]); - 117 13902 : return 0; + 114 468172 : unsigned pos_size = file_block_size(failed[failed_map[j]].file, failed[failed_map[j]].file_pos, state->block_size); + 115 468172 : if (blockcmp(state, rehash, failed[failed_map[j]].block, pos_size, buffer[failed[failed_map[j]].index], buffer_zero) != 0) { + 116 13896 : log_tag("hash_error: Hash mismatch on entry %u\n", failed_map[j]); + 117 13896 : return 0; 118 : } 119 : - 120 454438 : hash_checked = 1; + 120 454276 : hash_checked = 1; 121 : } 122 : } 123 : 124 : /* if nothing checked, we reject it */ 125 : /* note that we are excluding this case at upper level */ 126 : /* but checking again doesn't hurt */ - 127 195513 : if (!hash_checked) { + 127 195553 : if (!hash_checked) { 128 : /* LCOV_EXCL_START */ 129 : return 0; 130 : /* LCOV_EXCL_STOP */ @@ -194,8 +194,8 @@ 132 : 133 : /* if we checked something, and no block failed the check */ 134 : /* recompute all the redundancy information */ - 135 195513 : raid_gen(diskmax, state->level, state->block_size, buffer); - 136 195513 : return 1; + 135 195553 : raid_gen(diskmax, state->level, state->block_size, buffer); + 136 195553 : return 1; 137 : } 138 : 139 : /** @@ -221,7 +221,7 @@ 159 : * Return <0 if failure for missing strategy, >0 if data is wrong and we cannot rebuild correctly, 0 on success. 160 : * If success, the parity are computed in the buffer variable. 161 : */ - 162 260919 : static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) + 162 260805 : static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) 163 : { 164 : unsigned i, n; 165 : int error; @@ -230,7 +230,7 @@ 168 : int ip[LEV_MAX]; 169 : 170 : /* no fix required, already checked at higher level, but just to be sure */ - 171 260919 : if (failed_count == 0) { + 171 260805 : if (failed_count == 0) { 172 : /* LCOV_EXCL_START */ 173 : /* recompute only the parity */ 174 : raid_gen(diskmax, state->level, state->block_size, buffer); @@ -238,28 +238,28 @@ 176 : /* LCOV_EXCL_STOP */ 177 : } 178 : - 179 260919 : n = state->level; - 180 260919 : error = 0; + 179 260805 : n = state->level; + 180 260805 : error = 0; 181 : 182 : /* setup vector of failed disk indexes */ - 183 908931 : for (i = 0; i < failed_count; ++i) - 184 648012 : id[i] = failed[failed_map[i]].index; + 183 908349 : for (i = 0; i < failed_count; ++i) + 184 647544 : id[i] = failed[failed_map[i]].index; 185 : 186 : /* check if there is at least a failed block that can be checked for correctness using the hash */ 187 : /* if there isn't, we have to sacrifice a parity block to check that the result is correct */ - 188 260919 : has_hash = 0; - 189 908931 : for (i = 0; i < failed_count; ++i) { + 188 260805 : has_hash = 0; + 189 908349 : for (i = 0; i < failed_count; ++i) { 190 : /* if we are expected to recover this block */ - 191 648012 : if (!failed[failed_map[i]].is_outofdate + 191 647544 : if (!failed[failed_map[i]].is_outofdate 192 : /* if the block has a hash to check */ - 193 638968 : && block_has_updated_hash(failed[failed_map[i]].block) + 193 638500 : && block_has_updated_hash(failed[failed_map[i]].block) 194 : ) - 195 630582 : has_hash = 1; + 195 630114 : has_hash = 1; 196 : } 197 : 198 : /* if we don't have a hash, but we have an extra parity */ 199 : /* (strictly-less failures than number of parities) */ - 200 260919 : if (!has_hash && failed_count < n) { + 200 260805 : if (!has_hash && failed_count < n) { 201 : /* number of parity to use, one more to check the recovering */ 202 8386 : unsigned r = failed_count + 1; 203 : @@ -299,54 +299,54 @@ 237 : 238 : /* if we have a hash, and enough parities */ 239 : /* (less-or-equal failures than number of parities) */ - 240 252533 : if (has_hash && failed_count <= n) { + 240 252419 : if (has_hash && failed_count <= n) { 241 : /* number of parities to use equal at the number of failures */ - 242 204669 : unsigned r = failed_count; + 242 204707 : unsigned r = failed_count; 243 : 244 : /* all combinations (r of n) parities */ - 245 204669 : combination_first(r, n, ip); + 245 204707 : combination_first(r, n, ip); 246 : do { 247 : /* if a parity is missing, do nothing */ - 248 686926 : for (i = 0; i < r; ++i) { - 249 477511 : if (buffer_recov[ip[i]] == 0) + 248 686792 : for (i = 0; i < r; ++i) { + 249 477343 : if (buffer_recov[ip[i]] == 0) 250 4649 : break; 251 : } - 252 214064 : if (i != r) + 252 214098 : if (i != r) 253 4649 : continue; 254 : 255 : /* copy the parities to use */ - 256 682277 : for (i = 0; i < r; ++i) - 257 472862 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size); + 256 682143 : for (i = 0; i < r; ++i) + 257 472694 : memcpy(buffer[diskmax + ip[i]], buffer_recov[ip[i]], state->block_size); 258 : 259 : /* recover */ - 260 209415 : raid_data(r, id, ip, diskmax, state->block_size, buffer); + 260 209449 : raid_data(r, id, ip, diskmax, state->block_size, buffer); 261 : 262 : /* use the hash to check the result */ - 263 209415 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero)) - 264 195513 : return 0; + 263 209449 : if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero)) + 264 195553 : return 0; 265 : 266 : /* log */ - 267 13902 : log_tag("parity_error:%u:", pos); - 268 27804 : for (i = 0; i < r; ++i) { - 269 13902 : if (i != 0) + 267 13896 : log_tag("parity_error:%u:", pos); + 268 27792 : for (i = 0; i < r; ++i) { + 269 13896 : if (i != 0) 270 0 : log_tag("/"); - 271 13902 : log_tag("%s", lev_config_name(ip[i])); + 271 13896 : log_tag("%s", lev_config_name(ip[i])); 272 : } - 273 13902 : log_tag(":hash: Hash mismatch\n"); - 274 13902 : ++error; - 275 37102 : } while (combination_next(r, n, ip)); + 273 13896 : log_tag(":hash: Hash mismatch\n"); + 274 13896 : ++error; + 275 37090 : } while (combination_next(r, n, ip)); 276 : } 277 : 278 : /* return the number of failed attempts, or -1 if no strategy */ - 279 57020 : if (error) - 280 9156 : return error; + 279 56866 : if (error) + 280 9154 : return error; 281 : - 282 47864 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n", + 282 47712 : log_tag("strategy_error:%u: No strategy to recover from %u failures with %u parity %s hash\n", 283 : pos, failed_count, n, has_hash ? "with" : "without"); - 284 47864 : return -1; + 284 47712 : return -1; 285 : } 286 : - 287 869090 : static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) + 287 869089 : static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsigned diskmax, struct failed_struct* failed, unsigned* failed_map, unsigned failed_count, void** buffer, void** buffer_recov, void* buffer_zero) 288 : { 289 : int ret; 290 : int error; @@ -355,51 +355,51 @@ 293 : int something_to_recover; 294 : int something_unsynced; 295 : - 296 869090 : error = 0; + 296 869089 : error = 0; 297 : 298 : /* if nothing failed, just recompute the parity */ - 299 869090 : if (failed_count == 0) { - 300 581319 : raid_gen(diskmax, state->level, state->block_size, buffer); - 301 581319 : return 0; + 299 869089 : if (failed_count == 0) { + 300 581432 : raid_gen(diskmax, state->level, state->block_size, buffer); + 301 581432 : return 0; 302 : } 303 : 304 : /* logs the status */ - 305 1017302 : for (j = 0; j < failed_count; ++j) { + 305 1016720 : for (j = 0; j < failed_count; ++j) { 306 : const char* desc; 307 : const char* hash; 308 : const char* data; - 309 729531 : struct snapraid_block* block = failed[j].block; - 310 729531 : unsigned block_state = block_state_get(block); + 309 729063 : struct snapraid_block* block = failed[j].block; + 310 729063 : unsigned block_state = block_state_get(block); 311 : - 312 729531 : switch (block_state) { + 312 729063 : switch (block_state) { 313 18454 : case BLOCK_STATE_DELETED : desc = "delete"; break; 314 52081 : case BLOCK_STATE_CHG : desc = "change"; break; 315 24042 : case BLOCK_STATE_REP : desc = "replace"; break; - 316 634954 : case BLOCK_STATE_BLK : desc = "block"; break; + 316 634486 : case BLOCK_STATE_BLK : desc = "block"; break; 317 : /* LCOV_EXCL_START */ 318 : default : desc = "unknown"; break; 319 : /* LCOV_EXCL_STOP */ 320 : } 321 : - 322 729531 : if (hash_is_invalid(block->hash)) { + 322 729063 : if (hash_is_invalid(block->hash)) { 323 13841 : hash = "lost"; - 324 715690 : } else if (hash_is_zero(block->hash)) { + 324 715222 : } else if (hash_is_zero(block->hash)) { 325 29602 : hash = "zero"; 326 : } else { - 327 686088 : hash = "known"; + 327 685620 : hash = "known"; 328 : } 329 : - 330 729531 : if (failed[j].is_bad) - 331 643808 : data = "bad"; + 330 729063 : if (failed[j].is_bad) + 331 643340 : data = "bad"; 332 : else 333 85723 : data = "good"; 334 : - 335 729531 : if (failed[j].file) { - 336 711077 : struct snapraid_disk* disk = failed[j].disk; - 337 711077 : struct snapraid_file* file = failed[j].file; - 338 711077 : block_off_t file_pos = failed[j].file_pos; + 335 729063 : if (failed[j].file) { + 336 710609 : struct snapraid_disk* disk = failed[j].disk; + 337 710609 : struct snapraid_file* file = failed[j].file; + 338 710609 : block_off_t file_pos = failed[j].file_pos; 339 : - 340 711077 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc(file->sub), file_pos); + 340 710609 : log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc(file->sub), file_pos); 341 : } else { 342 18454 : log_tag("entry:%u:%s:%s:%s:\n", j, desc, hash, data); 343 : } @@ -421,35 +421,35 @@ 359 : /* We are interested to recover BLK, REP and CHG blocks if they are marked as bad, */ 360 : /* but we are not interested in DELETED ones. */ 361 : - 362 287771 : n = 0; - 363 287771 : something_to_recover = 0; /* keep track if there is at least one block to fix */ - 364 1017302 : for (j = 0; j < failed_count; ++j) { - 365 729531 : if (failed[j].is_bad) { - 366 643808 : unsigned block_state = block_state_get(failed[j].block); + 362 287657 : n = 0; + 363 287657 : something_to_recover = 0; /* keep track if there is at least one block to fix */ + 364 1016720 : for (j = 0; j < failed_count; ++j) { + 365 729063 : if (failed[j].is_bad) { + 366 643340 : unsigned block_state = block_state_get(failed[j].block); 367 : - 368 643808 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */ + 368 643340 : assert(block_state != BLOCK_STATE_DELETED); /* we cannot have bad DELETED blocks */ 369 : 370 : /* if we have the hash for it */ - 371 643808 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP) + 371 643340 : if ((block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP) 372 : /* try to fetch the block using the known hash */ - 373 635422 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0 - 374 630950 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0) + 373 634954 : && (state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0 + 374 630482 : || state_search_fetch(state, rehash, failed[j].file, failed[j].file_pos, failed[j].block, buffer[failed[j].index]) == 0) 375 : ) { 376 : /* we already have corrected it! */ 377 13884 : log_tag("hash_import: Fixed entry %u\n", j); 378 : } else { 379 : /* otherwise try to recover it */ - 380 629924 : failed_map[n] = j; - 381 629924 : ++n; + 380 629456 : failed_map[n] = j; + 381 629456 : ++n; 382 : 383 : /* we have something to try to recover */ - 384 629924 : something_to_recover = 1; + 384 629456 : something_to_recover = 1; 385 : } 386 : } 387 : } 388 : 389 : /* if nothing to fix */ - 390 287771 : if (!something_to_recover) { + 390 287657 : if (!something_to_recover) { 391 35896 : log_tag("recover_sync:%u:%u: Skipped for already recovered\n", pos, n); 392 : 393 : /* recompute only the parity */ @@ -457,22 +457,22 @@ 395 35896 : return 0; 396 : } 397 : - 398 251875 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero); - 399 251875 : if (ret == 0) { + 398 251761 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero); + 399 251761 : if (ret == 0) { 400 : /* reprocess the CHG blocks, for which we don't have a hash to check */ 401 : /* if they were BAD we have to use some euristics to ensure that we have recovered */ 402 : /* the state after the sync. If unsure, we assume the worst case */ 403 : - 404 683980 : for (j = 0; j < failed_count; ++j) { + 404 683858 : for (j = 0; j < failed_count; ++j) { 405 : /* we take care only of BAD blocks we have to write back */ - 406 484603 : if (failed[j].is_bad) { - 407 471091 : unsigned block_state = block_state_get(failed[j].block); + 406 484441 : if (failed[j].is_bad) { + 407 470929 : unsigned block_state = block_state_get(failed[j].block); 408 : 409 : /* BLK and REP blocks are always OK, because at this point */ 410 : /* we have already checked their hash */ - 411 471091 : if (block_state != BLOCK_STATE_CHG) { - 412 462705 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); - 413 462705 : continue; + 411 470929 : if (block_state != BLOCK_STATE_CHG) { + 412 462543 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); + 413 462543 : continue; 414 : } 415 : 416 : /* for CHG blocks we have to 'guess' if they are correct or not */ @@ -514,15 +514,15 @@ 452 : } 453 : } 454 : - 455 199377 : return 0; + 455 199417 : return 0; 456 : } - 457 52498 : if (ret > 0) - 458 9156 : error += ret; + 457 52344 : if (ret > 0) + 458 9154 : error += ret; 459 : - 460 52498 : if (ret < 0) - 461 43342 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n); + 460 52344 : if (ret < 0) + 461 43190 : log_tag("recover_sync:%u:%u: Failed with no attempts\n", pos, n); 462 : else - 463 9156 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret); + 463 9154 : log_tag("recover_sync:%u:%u: Failed with %d attempts\n", pos, n, ret); 464 : 465 : /* Now assume that the parity IS NOT updated at the current state, */ 466 : /* but still represent the state before the last 'sync' process. */ @@ -532,15 +532,15 @@ 470 : /* but we are not interested to recover CHG (new version) and REP (new version) blocks, */ 471 : /* even if marked as bad, because we don't have parity for them and it's just impossible, */ 472 : /* and we are not interested to recover DELETED ones. */ - 473 52498 : n = 0; - 474 52498 : something_to_recover = 0; /* keep track if there is at least one block to fix */ - 475 52498 : something_unsynced = 0; /* keep track if we have some unsynced info to process */ - 476 233164 : for (j = 0; j < failed_count; ++j) { - 477 180666 : unsigned block_state = block_state_get(failed[j].block); + 473 52344 : n = 0; + 474 52344 : something_to_recover = 0; /* keep track if there is at least one block to fix */ + 475 52344 : something_unsynced = 0; /* keep track if we have some unsynced info to process */ + 476 232704 : for (j = 0; j < failed_count; ++j) { + 477 180360 : unsigned block_state = block_state_get(failed[j].block); 478 : - 479 180666 : if (block_state == BLOCK_STATE_DELETED - 480 171622 : || block_state == BLOCK_STATE_CHG - 481 171622 : || block_state == BLOCK_STATE_REP + 479 180360 : if (block_state == BLOCK_STATE_DELETED + 480 171316 : || block_state == BLOCK_STATE_CHG + 481 171316 : || block_state == BLOCK_STATE_REP 482 : ) { 483 : /* If the block is CHG, REP or DELETED, we don't have the original content of block, */ 484 : /* and we must try to recover it. */ @@ -582,24 +582,24 @@ 520 : /* it also applies to CHG and DELETE blocks because we want to have */ 521 : /* a succesful recovering only if a BLK one is matching */ 522 9044 : failed[j].is_outofdate = 1; - 523 171622 : } else if (failed[j].is_bad) { + 523 171316 : } else if (failed[j].is_bad) { 524 : /* If the block is bad we don't know its content, and we try to recover it */ 525 : /* At this point, we can have only BLK ones */ 526 : - 527 171622 : assert(block_state == BLOCK_STATE_BLK); + 527 171316 : assert(block_state == BLOCK_STATE_BLK); 528 : 529 : /* we have something we are interested to recover */ - 530 171622 : something_to_recover = 1; + 530 171316 : something_to_recover = 1; 531 : 532 : /* we try to recover it */ - 533 171622 : failed_map[n] = j; - 534 171622 : ++n; + 533 171316 : failed_map[n] = j; + 534 171316 : ++n; 535 : } 536 : } 537 : 538 : /* if nothing to fix, we just don't try */ 539 : /* if nothing unsynced we also don't retry, because it's the same try as before */ - 540 52498 : if (something_to_recover && something_unsynced) { + 540 52344 : if (something_to_recover && something_unsynced) { 541 9044 : ret = repair_step(state, rehash, pos, diskmax, failed, failed_map, n, buffer, buffer_recov, buffer_zero); 542 9044 : if (ret == 0) { 543 : /* reprocess the REP and CHG blocks, for which we have recovered and old state */ @@ -633,17 +633,17 @@ 571 : else 572 0 : log_tag("recover_unsync:%u:%u: Failed with %d attempts\n", pos, n, ret); 573 : } else { - 574 43454 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n, + 574 43300 : log_tag("recover_unsync:%u:%u: Skipped for%s%s\n", pos, n, 575 : !something_to_recover ? " nothing to recover" : "", 576 : !something_unsynced ? " nothing unsynched" : "" 577 : ); 578 : } 579 : 580 : /* return the number of failed attempts, or -1 if no strategy */ - 581 47976 : if (error) - 582 4634 : return error; + 581 47822 : if (error) + 582 4632 : return error; 583 : else - 584 43342 : return -1; + 584 43190 : return -1; 585 : } 586 : 587 : /** @@ -715,12 +715,12 @@ 653 : /* rename it to .unrecoverable */ 654 : char path_to[PATH_MAX]; 655 : - 656 65043 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub); + 656 64972 : pathprint(path_to, sizeof(path_to), "%s%s.unrecoverable", disk->dir, file->sub); 657 : 658 : /* ensure to close the file before renaming */ - 659 65043 : if (handle[j].file == file) { - 660 65043 : ret = handle_close(&handle[j]); - 661 65043 : if (ret != 0) { + 659 64972 : if (handle[j].file == file) { + 660 64972 : ret = handle_close(&handle[j]); + 661 64972 : if (ret != 0) { 662 : /* LCOV_EXCL_START */ 663 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); 664 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); @@ -729,8 +729,8 @@ 667 : } 668 : } 669 : - 670 65043 : ret = rename(path, path_to); - 671 65043 : if (ret != 0) { + 670 64972 : ret = rename(path, path_to); + 671 64972 : if (ret != 0) { 672 : /* LCOV_EXCL_START */ 673 : log_fatal("Error renaming '%s' to '%s'. %s.\n", path, path_to, strerror(errno)); 674 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); @@ -738,22 +738,22 @@ 676 : /* LCOV_EXCL_STOP */ 677 : } 678 : - 679 65043 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub)); - 680 65043 : msg_info("unrecoverable %s\n", path); + 679 64972 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub)); + 680 64972 : msg_info("unrecoverable %s\n", path); 681 : 682 : /* and do not set the time if damaged */ - 683 65043 : goto close_and_continue; + 683 64972 : goto close_and_continue; 684 : } 685 : 686 : /* if the file is not fixed, meaning that it is untouched */ - 687 691999 : if (!file_flag_has(file, FILE_IS_FIXED)) { + 687 692070 : if (!file_flag_has(file, FILE_IS_FIXED)) { 688 : /* nothing to do, but close the file */ - 689 574163 : goto close_and_continue; + 689 574306 : goto close_and_continue; 690 : } 691 : 692 : /* if the file is closed or different than the one expected, reopen it */ 693 : /* a different open file could happen when filtering for bad blocks */ - 694 117836 : if (handle[j].file != file) { + 694 117764 : if (handle[j].file != file) { 695 : /* close a potential different file */ 696 0 : ret = handle_close(&handle[j]); 697 0 : if (ret != 0) { @@ -776,13 +776,13 @@ 714 : } 715 : } 716 : - 717 117836 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub)); - 718 117836 : msg_info("recovered %s\n", path); + 717 117764 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub)); + 718 117764 : msg_info("recovered %s\n", path); 719 : - 720 117836 : inode = handle[j].st.st_ino; + 720 117764 : inode = handle[j].st.st_ino; 721 : 722 : /* search for the corresponding inode */ - 723 117836 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); + 723 117764 : collide_file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); 724 : 725 : /* if the inode is already in the database and it refers at a different file name, */ 726 : /* we can fix the file time ONLY if the time and size allow to differentiate */ @@ -792,15 +792,15 @@ 730 : /* when recreating them the inodes may be reused in a different order, */ 731 : /* and at the next sync some files may have matching inode/size/time even if different name */ 732 : /* not allowing sync to detect that the file is changed and not renamed */ - 733 117836 : if (!collide_file /* if not in the database, there is no collision */ - 734 31552 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */ - 735 30029 : || collide_file->size != file->size /* if the size is different, the collision is identified */ - 736 8 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */ - 737 6 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */ + 733 117764 : if (!collide_file /* if not in the database, there is no collision */ + 734 29250 : || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */ + 735 27741 : || collide_file->size != file->size /* if the size is different, the collision is identified */ + 736 5 : || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */ + 737 3 : || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */ 738 : ) { 739 : /* set the original modification time */ - 740 117835 : ret = handle_utime(&handle[j]); - 741 235670 : if (ret == -1) { + 740 117763 : ret = handle_utime(&handle[j]); + 741 235526 : if (ret == -1) { 742 : /* LCOV_EXCL_START */ 743 : /* mark the file as damaged */ 744 : file_flag_set(file, FILE_IS_DAMAGED); @@ -815,21 +815,21 @@ 753 : /* we are not fixing, but only checking */ 754 : /* print just the final status */ 755 1307318 : if (file_flag_has(file, FILE_IS_DAMAGED)) { - 756 9521 : if (state->opt.auditonly) { - 757 2859 : log_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub)); - 758 2859 : msg_info("damaged %s\n", path); + 756 9389 : if (state->opt.auditonly) { + 757 2806 : log_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub)); + 758 2806 : msg_info("damaged %s\n", path); 759 : } else { - 760 6662 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub)); - 761 6662 : msg_info("unrecoverable %s\n", path); + 760 6583 : log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub)); + 761 6583 : msg_info("unrecoverable %s\n", path); 762 : } - 763 1297797 : } else if (file_flag_has(file, FILE_IS_FIXED)) { - 764 76467 : log_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub)); - 765 76467 : msg_info("recoverable %s\n", path); + 763 1297929 : } else if (file_flag_has(file, FILE_IS_FIXED)) { + 764 76370 : log_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub)); + 765 76370 : msg_info("recoverable %s\n", path); 766 : } else { - 767 1221330 : log_tag("status:correct:%s:%s\n", disk->name, esc(file->sub)); + 767 1221559 : log_tag("status:correct:%s:%s\n", disk->name, esc(file->sub)); 768 : /* we don't use msg_verbose() because it also goes into the log */ - 769 1221330 : if (msg_level >= MSG_VERBOSE) - 770 23175 : msg_info("correct %s\n", path); + 769 1221559 : if (msg_level >= MSG_VERBOSE) + 770 23233 : msg_info("correct %s\n", path); 771 : } 772 : } 773 : @@ -840,8 +840,8 @@ 778 2161101 : if (handle[j].file == file) { 779 : /* ensure to close the file just after finishing with it */ 780 : /* to avoid to keep it open without any possible use */ - 781 1975549 : ret = handle_close(&handle[j]); - 782 1975549 : if (ret != 0) { + 781 1975748 : ret = handle_close(&handle[j]); + 782 1975748 : if (ret != 0) { 783 : /* LCOV_EXCL_START */ 784 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); 785 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); @@ -870,13 +870,13 @@ 808 1866664 : if (state->opt.badonly) { 809 : /* skip if this is not bad */ 810 18684 : if (!info_get_bad(info)) - 811 15078 : return 0; + 811 15080 : return 0; 812 : } 813 : 814 : /* for each parity */ - 815 2120450 : for (l = 0; l < state->level; ++l) { - 816 2037334 : if (!state->parity[l].is_excluded) { - 817 1768470 : return 1; + 815 2120448 : for (l = 0; l < state->level; ++l) { + 816 2037332 : if (!state->parity[l].is_excluded) { + 817 1768468 : return 1; 818 : } 819 : } 820 : @@ -947,8 +947,8 @@ 885 118 : countmax = 0; 886 933450 : for (i = blockstart; i < blockmax; ++i) { 887 933332 : if (!block_is_enabled(state, i, handle, diskmax)) - 888 25065 : continue; - 889 908267 : ++countmax; + 888 25066 : continue; + 889 908266 : ++countmax; 890 : } 891 : 892 : /* check all the blocks in files */ @@ -963,15 +963,15 @@ 901 : 902 933332 : if (!block_is_enabled(state, i, handle, diskmax)) { 903 : /* post process the files */ - 904 25065 : ret = file_post(state, fix, i, handle, diskmax); - 905 25065 : if (ret == -1) { + 904 25066 : ret = file_post(state, fix, i, handle, diskmax); + 905 25066 : if (ret == -1) { 906 0 : log_fatal("Stopping at block %u\n", i); 907 0 : ++unrecoverable_error; 908 0 : goto bail; 909 : } 910 : 911 : /* and now continue with the next block */ - 912 25065 : continue; + 912 25066 : continue; 913 : } 914 : 915 : /* If we have valid parity, and it makes sense to check its content. */ @@ -979,19 +979,19 @@ 917 : /* but we don't report parity errors */ 918 : /* Note that with auditonly, we anyway skip the full parity check, */ 919 : /* because we also don't read it at all */ - 920 908267 : valid_parity = 1; + 920 908266 : valid_parity = 1; 921 : 922 : /* keep track of the number of failed blocks */ - 923 908267 : failed_count = 0; + 923 908266 : failed_count = 0; 924 : 925 : /* get block specific info */ - 926 908267 : info = info_get(&state->infoarr, i); + 926 908266 : info = info_get(&state->infoarr, i); 927 : 928 : /* if we have to use the old hash */ - 929 908267 : rehash = info_get_rehash(info); + 929 908266 : rehash = info_get_rehash(info); 930 : 931 : /* for each disk, process the block */ - 932 6357869 : for (j = 0; j < diskmax; ++j) { + 932 6357862 : for (j = 0; j < diskmax; ++j) { 933 : int read_size; 934 : unsigned char hash[HASH_SIZE]; 935 : struct snapraid_disk* disk; @@ -1001,26 +1001,26 @@ 939 : unsigned block_state; 940 : 941 : /* if the disk position is not used */ - 942 5449602 : disk = handle[j].disk; - 943 5449602 : if (!disk) { + 942 5449596 : disk = handle[j].disk; + 943 5449596 : if (!disk) { 944 : /* use an empty block */ 945 14013 : memset(buffer[j], 0, state->block_size); - 946 952540 : continue; + 946 951802 : continue; 947 : } 948 : 949 : /* if the disk block is not used */ - 950 5435589 : block = fs_par2block_get(disk, i); - 951 5435589 : if (block == BLOCK_EMPTY) { + 950 5435583 : block = fs_par2block_get(disk, i); + 951 5435583 : if (block == BLOCK_EMPTY) { 952 : /* use an empty block */ 953 188862 : memset(buffer[j], 0, state->block_size); 954 188862 : continue; 955 : } 956 : 957 : /* get the state of the block */ - 958 5246727 : block_state = block_state_get(block); + 958 5246721 : block_state = block_state_get(block); 959 : 960 : /* if the parity is not valid */ - 961 5246727 : if (block_has_invalid_parity(block)) { + 961 5246721 : if (block_has_invalid_parity(block)) { 962 : /* mark the parity as invalid, and don't try to check/fix it */ 963 : /* because it will be recomputed at the next sync */ 964 94577 : valid_parity = 0; @@ -1028,7 +1028,7 @@ 966 : } 967 : 968 : /* if the block is DELETED */ - 969 5246727 : if (block_state == BLOCK_STATE_DELETED) { + 969 5246721 : if (block_state == BLOCK_STATE_DELETED) { 970 : /* use an empty block */ 971 18454 : memset(buffer[j], 0, state->block_size); 972 : @@ -1047,10 +1047,10 @@ 985 : } 986 : 987 : /* get the file of this block */ - 988 5228273 : file = fs_par2file_get(disk, i, &file_pos); + 988 5228267 : file = fs_par2file_get(disk, i, &file_pos); 989 : 990 : /* if we are only hashing, we can skip excluded files and don't even read them */ - 991 5228273 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) { + 991 5228267 : if (state->opt.auditonly && file_flag_has(file, FILE_IS_EXCLUDED)) { 992 : /* use an empty block */ 993 : /* in true, this is unnecessary, becase we are not checking any parity */ 994 : /* but we keep it for completeness */ @@ -1059,10 +1059,10 @@ 997 : } 998 : 999 : /* if the file is closed or different than the current one */ - 1000 5228273 : if (handle[j].file == 0 || handle[j].file != file) { + 1000 5228267 : if (handle[j].file == 0 || handle[j].file != file) { 1001 : /* close the old one, if any */ - 1002 2259132 : ret = handle_close(&handle[j]); - 1003 2259132 : if (ret == -1) { + 1002 2258931 : ret = handle_close(&handle[j]); + 1003 2258931 : if (ret == -1) { 1004 : /* LCOV_EXCL_START */ 1005 : log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(handle[j].file->sub), strerror(errno)); 1006 : log_fatal("DANGER! Unexpected close error in a data disk.\n"); @@ -1073,10 +1073,10 @@ 1011 : } 1012 : 1013 : /* if fixing, and the file is not excluded, we must open for writing */ - 1014 2259132 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) { + 1014 2258931 : if (fix && !file_flag_has(file, FILE_IS_EXCLUDED)) { 1015 : /* if fixing, create the file, open for writing and resize if required */ - 1016 771245 : ret = handle_create(&handle[j], file, state->file_mode); - 1017 771245 : if (ret == -1) { + 1016 771210 : ret = handle_create(&handle[j], file, state->file_mode); + 1017 771210 : if (ret == -1) { 1018 : /* LCOV_EXCL_START */ 1019 : if (errno == EACCES) { 1020 : log_fatal("WARNING! Please give write permission to the file.\n"); @@ -1090,69 +1090,69 @@ 1028 : } 1029 : 1030 : /* check if the file was just created */ - 1031 1542490 : if (handle[j].created != 0) { + 1031 1542420 : if (handle[j].created != 0) { 1032 : /* if fragmented, it may be reopened, so remember that the file */ 1033 : /* was originally missing */ - 1034 113043 : file_flag_set(file, FILE_IS_CREATED); + 1034 113024 : file_flag_set(file, FILE_IS_CREATED); 1035 : } 1036 : } else { 1037 : /* open the file only for reading */ - 1038 1487887 : if (!file_flag_has(file, FILE_IS_MISSING)) - 1039 1372035 : ret = handle_open(&handle[j], file, state->file_mode, - 1040 1372035 : log_error, state->opt.expected_missing ? log_expected : 0); + 1038 1487721 : if (!file_flag_has(file, FILE_IS_MISSING)) + 1039 1372062 : ret = handle_open(&handle[j], file, state->file_mode, + 1040 1372062 : log_error, state->opt.expected_missing ? log_expected : 0); 1041 : else - 1042 115852 : ret = -1; /* if the file is missing, we cannot open it */ - 1043 1487887 : if (ret == -1) { + 1042 115659 : ret = -1; /* if the file is missing, we cannot open it */ + 1043 1487721 : if (ret == -1) { 1044 : /* save the failed block for the check/fix */ - 1045 194739 : failed[failed_count].is_bad = 1; - 1046 194739 : failed[failed_count].is_outofdate = 0; - 1047 194739 : failed[failed_count].index = j; - 1048 194739 : failed[failed_count].block = block; - 1049 194739 : failed[failed_count].disk = disk; - 1050 194739 : failed[failed_count].file = file; - 1051 194739 : failed[failed_count].file_pos = file_pos; - 1052 194739 : failed[failed_count].handle = &handle[j]; - 1053 194739 : ++failed_count; + 1045 194418 : failed[failed_count].is_bad = 1; + 1046 194418 : failed[failed_count].is_outofdate = 0; + 1047 194418 : failed[failed_count].index = j; + 1048 194418 : failed[failed_count].block = block; + 1049 194418 : failed[failed_count].disk = disk; + 1050 194418 : failed[failed_count].file = file; + 1051 194418 : failed[failed_count].file_pos = file_pos; + 1052 194418 : failed[failed_count].handle = &handle[j]; + 1053 194418 : ++failed_count; 1054 : - 1055 194739 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), file_pos); - 1056 194739 : ++error; + 1055 194418 : log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), file_pos); + 1056 194418 : ++error; 1057 : 1058 : /* mark the file as missing, to avoid to retry to open it again */ 1059 : /* note that this can be done only if we are not fixing it */ 1060 : /* otherwise, it could be recreated */ - 1061 194739 : file_flag_set(file, FILE_IS_MISSING); - 1062 194739 : continue; + 1061 194418 : file_flag_set(file, FILE_IS_MISSING); + 1062 194418 : continue; 1063 : } 1064 : } 1065 : 1066 : /* if it's the first open, and not excluded */ - 1067 2064393 : if (!file_flag_has(file, FILE_IS_OPENED) - 1068 2049054 : && !file_flag_has(file, FILE_IS_EXCLUDED)) { + 1067 2064513 : if (!file_flag_has(file, FILE_IS_OPENED) + 1068 2049148 : && !file_flag_has(file, FILE_IS_EXCLUDED)) { 1069 : 1070 : /* check if the file is changed */ - 1071 1997699 : if (handle[j].st.st_size != file->size - 1072 1804789 : || handle[j].st.st_mtime != file->mtime_sec - 1073 1780584 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec + 1071 1997793 : if (handle[j].st.st_size != file->size + 1072 1804861 : || handle[j].st.st_mtime != file->mtime_sec + 1073 1780308 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec 1074 : /* don't check the inode to support filesystem without persistent inodes */ 1075 : ) { 1076 : /* report that the file is not synced */ - 1077 217115 : file_flag_set(file, FILE_IS_UNSYNCED); + 1077 217485 : file_flag_set(file, FILE_IS_UNSYNCED); 1078 : } 1079 : } 1080 : 1081 : /* if it's the first open, and not excluded and larger */ - 1082 2064393 : if (!file_flag_has(file, FILE_IS_OPENED) - 1083 2049054 : && !file_flag_has(file, FILE_IS_EXCLUDED) - 1084 1997699 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED)) - 1085 1997699 : && handle[j].st.st_size > file->size + 1082 2064513 : if (!file_flag_has(file, FILE_IS_OPENED) + 1083 2049148 : && !file_flag_has(file, FILE_IS_EXCLUDED) + 1084 1997793 : && !(state->opt.syncedonly && file_flag_has(file, FILE_IS_UNSYNCED)) + 1085 1997793 : && handle[j].st.st_size > file->size 1086 : ) { - 1087 8622 : log_error("File '%s' is larger than expected.\n", handle[j].path); - 1088 8622 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub)); - 1089 8622 : ++error; + 1087 8781 : log_error("File '%s' is larger than expected.\n", handle[j].path); + 1088 8781 : log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub)); + 1089 8781 : ++error; 1090 : - 1091 8622 : if (fix) { - 1092 3177 : ret = handle_truncate(&handle[j], file); - 1093 3177 : if (ret == -1) { + 1091 8781 : if (fix) { + 1092 3249 : ret = handle_truncate(&handle[j], file); + 1093 3249 : if (ret == -1) { 1094 : /* LCOV_EXCL_START */ 1095 : log_fatal("DANGER! Unexpected truncate error in a data disk, it isn't possible to fix.\n"); 1096 : log_fatal("Stopping at block %u\n", i); @@ -1161,43 +1161,43 @@ 1099 : /* LCOV_EXCL_STOP */ 1100 : } 1101 : - 1102 3177 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub)); - 1103 3177 : ++recovered_error; + 1102 3249 : log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub)); + 1103 3249 : ++recovered_error; 1104 : } 1105 : } 1106 : 1107 : /* mark the file as opened at least one time */ 1108 : /* this is used to avoid to check the unsynced and size */ 1109 : /* more than one time, in case the file is reopened later */ - 1110 2064393 : file_flag_set(file, FILE_IS_OPENED); + 1110 2064513 : file_flag_set(file, FILE_IS_OPENED); 1111 : } 1112 : 1113 : /* read from the file */ - 1114 5033534 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, - 1115 5033534 : log_error, state->opt.expected_missing ? log_expected : 0); - 1116 5033534 : if (read_size == -1) { + 1114 5033849 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, + 1115 5033849 : log_error, state->opt.expected_missing ? log_expected : 0); + 1116 5033849 : if (read_size == -1) { 1117 : /* save the failed block for the check/fix */ - 1118 442375 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */ - 1119 442375 : failed[failed_count].is_outofdate = 0; - 1120 442375 : failed[failed_count].index = j; - 1121 442375 : failed[failed_count].block = block; - 1122 442375 : failed[failed_count].disk = disk; - 1123 442375 : failed[failed_count].file = file; - 1124 442375 : failed[failed_count].file_pos = file_pos; - 1125 442375 : failed[failed_count].handle = &handle[j]; - 1126 442375 : ++failed_count; + 1118 442025 : failed[failed_count].is_bad = 1; /* it's bad because we cannot read it */ + 1119 442025 : failed[failed_count].is_outofdate = 0; + 1120 442025 : failed[failed_count].index = j; + 1121 442025 : failed[failed_count].block = block; + 1122 442025 : failed[failed_count].disk = disk; + 1123 442025 : failed[failed_count].file = file; + 1124 442025 : failed[failed_count].file_pos = file_pos; + 1125 442025 : failed[failed_count].handle = &handle[j]; + 1126 442025 : ++failed_count; 1127 : - 1128 442375 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), file_pos); - 1129 442375 : ++error; - 1130 442375 : continue; + 1128 442025 : log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), file_pos); + 1129 442025 : ++error; + 1130 442025 : continue; 1131 : } 1132 : - 1133 4591159 : countsize += read_size; + 1133 4591824 : countsize += read_size; 1134 : 1135 : /* always insert CHG blocks, the repair functions needs all of them */ 1136 : /* because the parity may be still referring at the old state */ 1137 : /* and the repair must be aware of it */ - 1138 4591159 : if (block_state == BLOCK_STATE_CHG) { + 1138 4591824 : if (block_state == BLOCK_STATE_CHG) { 1139 : /* we DO NOT mark them as bad to avoid to overwrite them with wrong data. */ 1140 : /* if we don't have a hash, we always assume the first read of the block correct. */ 1141 43695 : failed[failed_count].is_bad = 0; /* we assume the CHG block correct */ @@ -1212,39 +1212,39 @@ 1150 43695 : continue; 1151 : } 1152 : - 1153 4547464 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); + 1153 4548129 : assert(block_state == BLOCK_STATE_BLK || block_state == BLOCK_STATE_REP); 1154 : 1155 : /* compute the hash of the block just read */ - 1156 4547464 : if (rehash) { - 1157 286659 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size); + 1156 4548129 : if (rehash) { + 1157 286660 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size); 1158 : } else { - 1159 4260805 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size); + 1159 4261469 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size); 1160 : } 1161 : 1162 : /* compare the hash */ - 1163 4547464 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { - 1164 12815 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE); + 1163 4548129 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { + 1164 12748 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE); 1165 : 1166 : /* save the failed block for the check/fix */ - 1167 12815 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */ - 1168 12815 : failed[failed_count].is_outofdate = 0; - 1169 12815 : failed[failed_count].index = j; - 1170 12815 : failed[failed_count].block = block; - 1171 12815 : failed[failed_count].disk = disk; - 1172 12815 : failed[failed_count].file = file; - 1173 12815 : failed[failed_count].file_pos = file_pos; - 1174 12815 : failed[failed_count].handle = &handle[j]; - 1175 12815 : ++failed_count; + 1167 12748 : failed[failed_count].is_bad = 1; /* it's bad because the hash doesn't match */ + 1168 12748 : failed[failed_count].is_outofdate = 0; + 1169 12748 : failed[failed_count].index = j; + 1170 12748 : failed[failed_count].block = block; + 1171 12748 : failed[failed_count].disk = disk; + 1172 12748 : failed[failed_count].file = file; + 1173 12748 : failed[failed_count].file_pos = file_pos; + 1174 12748 : failed[failed_count].handle = &handle[j]; + 1175 12748 : ++failed_count; 1176 : - 1177 12815 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff); - 1178 12815 : ++error; - 1179 12815 : continue; + 1177 12748 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff); + 1178 12748 : ++error; + 1179 12748 : continue; 1180 : } 1181 : 1182 : /* always insert REP blocks, the repair functions needs all of them */ 1183 : /* because the parity may be still referring at the old state */ 1184 : /* and the repair must be aware of it */ - 1185 4534649 : if (block_state == BLOCK_STATE_REP) { + 1185 4535381 : if (block_state == BLOCK_STATE_REP) { 1186 23574 : failed[failed_count].is_bad = 0; /* it's not bad */ 1187 23574 : failed[failed_count].is_outofdate = 0; 1188 23574 : failed[failed_count].index = j; @@ -1259,24 +1259,24 @@ 1197 : } 1198 : 1199 : /* now read and check the parity if requested */ - 1200 908267 : if (!state->opt.auditonly) { + 1200 908266 : if (!state->opt.auditonly) { 1201 : void* buffer_recov[LEV_MAX]; 1202 : void* buffer_zero; 1203 : 1204 : /* buffers for parity read and not computed */ - 1205 4161705 : for (l = 0; l < state->level; ++l) - 1206 3292615 : buffer_recov[l] = buffer[diskmax + state->level + l]; - 1207 2791015 : for (; l < LEV_MAX; ++l) + 1205 4161698 : for (l = 0; l < state->level; ++l) + 1206 3292609 : buffer_recov[l] = buffer[diskmax + state->level + l]; + 1207 2791014 : for (; l < LEV_MAX; ++l) 1208 1921925 : buffer_recov[l] = 0; 1209 : 1210 : /* the zero buffer is the last one */ - 1211 869090 : buffer_zero = buffer[buffermax - 1]; + 1211 869089 : buffer_zero = buffer[buffermax - 1]; 1212 : 1213 : /* read the parity */ - 1214 4161705 : for (l = 0; l < state->level; ++l) { - 1215 3292615 : if (parity[l]) { - 1216 3278745 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error); - 1217 3278745 : if (ret == -1) { + 1214 4161698 : for (l = 0; l < state->level; ++l) { + 1215 3292609 : if (parity[l]) { + 1216 3278739 : ret = parity_read(parity[l], i, buffer_recov[l], state->block_size, log_error); + 1217 3278739 : if (ret == -1) { 1218 90275 : buffer_recov[l] = 0; /* no parity to use */ 1219 : 1220 90275 : log_tag("parity_error:%u:%s: Read error\n", i, lev_config_name(l)); @@ -1288,38 +1288,38 @@ 1226 : } 1227 : 1228 : /* try all the recovering strategies */ - 1229 869090 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero); - 1230 869090 : if (ret != 0) { + 1229 869089 : ret = repair(state, rehash, i, diskmax, failed, failed_map, failed_count, buffer, buffer_recov, buffer_zero); + 1230 869089 : if (ret != 0) { 1231 : /* increment the number of errors */ - 1232 47976 : if (ret > 0) - 1233 4634 : error += ret; - 1234 47976 : ++unrecoverable_error; + 1232 47822 : if (ret > 0) + 1233 4632 : error += ret; + 1234 47822 : ++unrecoverable_error; 1235 : 1236 : /* print a list of all the errors in files */ - 1237 219598 : for (j = 0; j < failed_count; ++j) { - 1238 171622 : if (failed[j].is_bad) - 1239 167100 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); + 1237 219138 : for (j = 0; j < failed_count; ++j) { + 1238 171316 : if (failed[j].is_bad) + 1239 166794 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); 1240 : } 1241 : 1242 : /* keep track of damaged files */ - 1243 219598 : for (j = 0; j < failed_count; ++j) { - 1244 171622 : if (failed[j].is_bad) - 1245 167100 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); + 1243 219138 : for (j = 0; j < failed_count; ++j) { + 1244 171316 : if (failed[j].is_bad) + 1245 166794 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); 1246 : } 1247 : } else { 1248 : /* now counts partial recovers */ 1249 : /* note that this could happen only when we have an incomplete 'sync' */ 1250 : /* and that we have recovered is the state before the 'sync' */ - 1251 821114 : int partial_recover_error = 0; + 1251 821267 : int partial_recover_error = 0; 1252 : 1253 : /* print a list of all the errors in files */ - 1254 1379023 : for (j = 0; j < failed_count; ++j) { - 1255 557909 : if (failed[j].is_bad && failed[j].is_outofdate) { + 1254 1379014 : for (j = 0; j < failed_count; ++j) { + 1255 557747 : if (failed[j].is_bad && failed[j].is_outofdate) { 1256 4192 : ++partial_recover_error; 1257 4192 : log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); 1258 : } 1259 : } - 1260 821114 : if (partial_recover_error != 0) { + 1260 821267 : if (partial_recover_error != 0) { 1261 4192 : error += partial_recover_error; 1262 4192 : ++unrecoverable_error; 1263 : } @@ -1327,36 +1327,36 @@ 1265 : /* now check parities, but only if all the blocks have it computed */ 1266 : /* if you check/fix after a partial sync, it's OK to have parity errors on the blocks with invalid parity */ 1267 : /* and doesn't make sense to try to fix it */ - 1268 821114 : if (valid_parity) { + 1268 821267 : if (valid_parity) { 1269 : /* check the parity */ - 1270 3718850 : for (l = 0; l < state->level; ++l) { - 1271 2959425 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) { - 1272 10638 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size); + 1270 3719151 : for (l = 0; l < state->level; ++l) { + 1271 2959573 : if (buffer_recov[l] != 0 && memcmp(buffer_recov[l], buffer[diskmax + l], state->block_size) != 0) { + 1272 10640 : unsigned diff = memdiff(buffer_recov[l], buffer[diskmax + l], state->block_size); 1273 : 1274 : /* mark that the read parity is wrong, setting ptr to 0 */ - 1275 10638 : buffer_recov[l] = 0; + 1275 10640 : buffer_recov[l] = 0; 1276 : - 1277 10638 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff); - 1278 10638 : ++error; + 1277 10640 : log_tag("parity_error:%u:%s: Data error, diff bits %u\n", i, lev_config_name(l), diff); + 1278 10640 : ++error; 1279 : } 1280 : } 1281 : } 1282 : 1283 : /* now write recovered files */ - 1284 821114 : if (fix) { + 1284 821267 : if (fix) { 1285 : /* update the fixed files */ - 1286 651778 : for (j = 0; j < failed_count; ++j) { + 1286 651810 : for (j = 0; j < failed_count; ++j) { 1287 : /* nothing to do if it doesn't need recovering */ - 1288 337832 : if (!failed[j].is_bad) + 1288 337787 : if (!failed[j].is_bad) 1289 40318 : continue; 1290 : 1291 : /* do not fix if the file is excluded */ - 1292 297514 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED) - 1293 288250 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED))) + 1292 297469 : if (file_flag_has(failed[j].file, FILE_IS_EXCLUDED) + 1293 288205 : || (state->opt.syncedonly && file_flag_has(failed[j].file, FILE_IS_UNSYNCED))) 1294 9264 : continue; 1295 : - 1296 288250 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size); - 1297 288250 : if (ret == -1) { + 1296 288205 : ret = handle_write(failed[j].handle, failed[j].file_pos, buffer[failed[j].index], state->block_size); + 1297 288205 : if (ret == -1) { 1298 : /* LCOV_EXCL_START */ 1299 : /* mark the file as damaged */ 1300 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); @@ -1374,7 +1374,7 @@ 1312 : } 1313 : 1314 : /* if we are not sure that the recovered content is uptodate */ - 1315 288250 : if (failed[j].is_outofdate) { + 1315 288205 : if (failed[j].is_outofdate) { 1316 : /* mark the file as damaged */ 1317 4192 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); 1318 4192 : continue; @@ -1382,20 +1382,20 @@ 1320 : 1321 : /* mark the file as containing some fixes */ 1322 : /* note that it could be also marked as damaged in other iterations */ - 1323 284058 : file_flag_set(failed[j].file, FILE_IS_FIXED); + 1323 284013 : file_flag_set(failed[j].file, FILE_IS_FIXED); 1324 : - 1325 284058 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); - 1326 284058 : ++recovered_error; + 1325 284013 : log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); + 1326 284013 : ++recovered_error; 1327 : } 1328 : 1329 : /* update parity only if all the blocks have it computed */ 1330 : /* if you check/fix after a partial sync, you do not want to fix parity */ 1331 : /* for blocks that are going to have it computed in the sync completion */ - 1332 313946 : if (valid_parity) { + 1332 314023 : if (valid_parity) { 1333 : /* update the parity */ - 1334 961633 : for (l = 0; l < state->level; ++l) { + 1334 961782 : for (l = 0; l < state->level; ++l) { 1335 : /* if the parity on disk is wrong */ - 1336 696859 : if (buffer_recov[l] == 0 + 1336 696931 : if (buffer_recov[l] == 0 1337 : /* and we have access at the parity */ 1338 67199 : && parity[l] != 0 1339 : /* and the parity is not excluded */ @@ -1420,9 +1420,9 @@ 1358 : } else { 1359 : /* if we are not fixing, we just set the FIXED flag */ 1360 : /* meaning that we could fix this file if we try */ - 1361 727245 : for (j = 0; j < failed_count; ++j) { - 1362 220077 : if (failed[j].is_bad) { - 1363 179194 : file_flag_set(failed[j].file, FILE_IS_FIXED); + 1361 727204 : for (j = 0; j < failed_count; ++j) { + 1362 219960 : if (failed[j].is_bad) { + 1363 179077 : file_flag_set(failed[j].file, FILE_IS_FIXED); 1364 : } 1365 : } 1366 : } @@ -1430,26 +1430,26 @@ 1368 : } else { 1369 : /* if we are not checking, we just set the DAMAGED flag */ 1370 : /* to report that the file is damaged, and we don't know if we can fix it */ - 1371 45298 : for (j = 0; j < failed_count; ++j) { - 1372 6121 : if (failed[j].is_bad) { - 1373 6121 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); + 1371 45028 : for (j = 0; j < failed_count; ++j) { + 1372 5851 : if (failed[j].is_bad) { + 1373 5851 : file_flag_set(failed[j].file, FILE_IS_DAMAGED); 1374 : } 1375 : } 1376 : } 1377 : 1378 : /* post process the files */ - 1379 908267 : ret = file_post(state, fix, i, handle, diskmax); - 1380 908267 : if (ret == -1) { + 1379 908266 : ret = file_post(state, fix, i, handle, diskmax); + 1380 908266 : if (ret == -1) { 1381 0 : log_fatal("Stopping at block %u\n", i); 1382 0 : ++unrecoverable_error; 1383 0 : goto bail; 1384 : } 1385 : 1386 : /* count the number of processed block */ - 1387 908267 : ++countpos; + 1387 908266 : ++countpos; 1388 : 1389 : /* progress */ - 1390 908267 : if (state_progress(state, i, countpos, countmax, countsize)) { + 1390 908266 : if (state_progress(state, i, countpos, countmax, countsize)) { 1391 : /* LCOV_EXCL_START */ 1392 : break; 1393 : /* LCOV_EXCL_STOP */ @@ -1467,52 +1467,52 @@ 1405 : /* for each empty file in the disk */ 1406 705 : disk = handle[i].disk; 1407 705 : node = disk->filelist; - 1408 2187839 : while (node) { + 1408 2187957 : while (node) { 1409 : char path[PATH_MAX]; 1410 : struct stat st; 1411 : struct snapraid_file* file; - 1412 2186429 : int unsuccesful = 0; + 1412 2186547 : int unsuccesful = 0; 1413 : - 1414 2186429 : file = node->data; - 1415 2186429 : node = node->next; /* next node */ + 1414 2186547 : file = node->data; + 1415 2186547 : node = node->next; /* next node */ 1416 : 1417 : /* if not empty, it's already checked and continue to the next one */ - 1418 2186429 : if (file->size != 0) { - 1419 4367351 : continue; + 1418 2186547 : if (file->size != 0) { + 1419 4367359 : continue; 1420 : } 1421 : 1422 : /* if excluded continue to the next one */ - 1423 2834 : if (file_flag_has(file, FILE_IS_EXCLUDED)) { - 1424 161 : continue; + 1423 2952 : if (file_flag_has(file, FILE_IS_EXCLUDED)) { + 1424 169 : continue; 1425 : } 1426 : 1427 : /* stat the file */ - 1428 2673 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub); - 1429 2673 : ret = stat(path, &st); - 1430 2673 : if (ret == -1) { - 1431 162 : unsuccesful = 1; + 1428 2783 : pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub); + 1429 2783 : ret = stat(path, &st); + 1430 2783 : if (ret == -1) { + 1431 173 : unsuccesful = 1; 1432 : - 1433 162 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno)); - 1434 162 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub)); - 1435 162 : ++error; - 1436 2511 : } else if (!S_ISREG(st.st_mode)) { + 1433 173 : log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno)); + 1434 173 : log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub)); + 1435 173 : ++error; + 1436 2610 : } else if (!S_ISREG(st.st_mode)) { 1437 0 : unsuccesful = 1; 1438 : 1439 0 : log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc(file->sub)); 1440 0 : ++error; - 1441 2511 : } else if (st.st_size != 0) { - 1442 6 : unsuccesful = 1; + 1441 2610 : } else if (st.st_size != 0) { + 1442 8 : unsuccesful = 1; 1443 : - 1444 6 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size); - 1445 6 : ++error; + 1444 8 : log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size); + 1445 8 : ++error; 1446 : } 1447 : - 1448 2673 : if (fix && unsuccesful) { + 1448 2783 : if (fix && unsuccesful) { 1449 : int f; 1450 : 1451 : /* create the ancestor directories */ - 1452 151 : ret = mkancestor(path); - 1453 151 : if (ret != 0) { + 1452 158 : ret = mkancestor(path); + 1453 158 : if (ret != 0) { 1454 : /* LCOV_EXCL_START */ 1455 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); 1456 : log_fatal("Stopping\n"); @@ -1523,8 +1523,8 @@ 1461 : 1462 : /* create it */ 1463 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ - 1464 151 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600); - 1465 151 : if (f == -1) { + 1464 158 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600); + 1465 158 : if (f == -1) { 1466 : /* LCOV_EXCL_START */ 1467 : log_fatal("Error creating empty file '%s'. %s.\n", path, strerror(errno)); 1468 : if (errno == EACCES) { @@ -1540,8 +1540,8 @@ 1478 : } 1479 : 1480 : /* set the original modification time */ - 1481 151 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec); - 1482 151 : if (ret != 0) { + 1481 158 : ret = fmtime(f, file->mtime_sec, file->mtime_nsec); + 1482 158 : if (ret != 0) { 1483 : /* LCOV_EXCL_START */ 1484 : close(f); 1485 : @@ -1554,8 +1554,8 @@ 1492 : } 1493 : 1494 : /* close it */ - 1495 151 : ret = close(f); - 1496 151 : if (ret != 0) { + 1495 158 : ret = close(f); + 1496 158 : if (ret != 0) { 1497 : /* LCOV_EXCL_START */ 1498 : log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); 1499 : log_fatal("Stopping\n"); @@ -1564,11 +1564,11 @@ 1502 : /* LCOV_EXCL_STOP */ 1503 : } 1504 : - 1505 151 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub)); - 1506 151 : ++recovered_error; + 1505 158 : log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub)); + 1506 158 : ++recovered_error; 1507 : - 1508 151 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub)); - 1509 151 : msg_info("recovered %s%s\n", disk->dir, file->sub); + 1508 158 : log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub)); + 1509 158 : msg_info("recovered %s%s\n", disk->dir, file->sub); 1510 : } 1511 : } 1512 : @@ -1650,25 +1650,25 @@ 1588 66532 : pathprint(path, sizeof(path), "%s%s", disk->dir, slink->sub); 1589 66532 : ret = readlink(path, linkto, sizeof(linkto)); 1590 66532 : if (ret < 0) { - 1591 4257 : unsuccesful = 1; + 1591 4337 : unsuccesful = 1; 1592 : - 1593 4257 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno)); - 1594 4257 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub)); - 1595 4257 : ++error; - 1596 62275 : } else if (ret >= PATH_MAX) { + 1593 4337 : log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno)); + 1594 4337 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub)); + 1595 4337 : ++error; + 1596 62195 : } else if (ret >= PATH_MAX) { 1597 0 : unsuccesful = 1; 1598 : 1599 0 : log_error("Error reading symlink '%s'. Symlink too long.\n", path); 1600 0 : log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub)); 1601 0 : ++error; 1602 : } else { - 1603 62275 : linkto[ret] = 0; + 1603 62195 : linkto[ret] = 0; 1604 : - 1605 62275 : if (strcmp(linkto, slink->linkto) != 0) { - 1606 574 : unsuccesful = 1; + 1605 62195 : if (strcmp(linkto, slink->linkto) != 0) { + 1606 493 : unsuccesful = 1; 1607 : - 1608 574 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(slink->sub), linkto, slink->linkto); - 1609 574 : ++error; + 1608 493 : log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(slink->sub), linkto, slink->linkto); + 1609 493 : ++error; 1610 : } 1611 : } 1612 : } @@ -1846,23 +1846,23 @@ 1784 : /* for each file in the disk */ 1785 269 : disk = handle[i].disk; 1786 269 : node = disk->filelist; - 1787 870354 : while (node) { + 1787 870399 : while (node) { 1788 : char path[PATH_MAX]; 1789 : struct snapraid_file* file; 1790 : - 1791 869816 : file = node->data; - 1792 869816 : node = node->next; /* next node */ + 1791 869861 : file = node->data; + 1792 869861 : node = node->next; /* next node */ 1793 : 1794 : /* if the file was not created, meaning that it was already existing */ - 1795 869816 : if (!file_flag_has(file, FILE_IS_CREATED)) { + 1795 869861 : if (!file_flag_has(file, FILE_IS_CREATED)) { 1796 : /* nothing to do */ - 1797 1626589 : continue; + 1797 1626698 : continue; 1798 : } 1799 : 1800 : /* if processing was finished */ - 1801 113043 : if (file_flag_has(file, FILE_IS_FINISHED)) { + 1801 113024 : if (file_flag_has(file, FILE_IS_FINISHED)) { 1802 : /* nothing to do */ - 1803 113043 : continue; + 1803 113024 : continue; 1804 : } 1805 : 1806 : /* if the file was originally missing, and processing not yet finished */ diff --git a/cov/cmdline/device.c.func-sort-c.html b/cov/cmdline/device.c.func-sort-c.html index a95a8d8e..566e5929 100644 --- a/cov/cmdline/device.c.func-sort-c.html +++ b/cov/cmdline/device.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 diff --git a/cov/cmdline/device.c.func.html b/cov/cmdline/device.c.func.html index a2e66645..b0da8a8b 100644 --- a/cov/cmdline/device.c.func.html +++ b/cov/cmdline/device.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 diff --git a/cov/cmdline/device.c.gcov.html b/cov/cmdline/device.c.gcov.html index 9dd230f0..1014045d 100644 --- a/cov/cmdline/device.c.gcov.html +++ b/cov/cmdline/device.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 diff --git a/cov/cmdline/dry.c.func-sort-c.html b/cov/cmdline/dry.c.func-sort-c.html index a6ab1ed9..ac636230 100644 --- a/cov/cmdline/dry.c.func-sort-c.html +++ b/cov/cmdline/dry.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/cmdline/dry.c.func.html b/cov/cmdline/dry.c.func.html index 70114cd4..05c93ac8 100644 --- a/cov/cmdline/dry.c.func.html +++ b/cov/cmdline/dry.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/cmdline/dry.c.gcov.html b/cov/cmdline/dry.c.gcov.html index c8155f8f..52891e1b 100644 --- a/cov/cmdline/dry.c.gcov.html +++ b/cov/cmdline/dry.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/cmdline/dup.c.func-sort-c.html b/cov/cmdline/dup.c.func-sort-c.html index 071408f7..0817fb38 100644 --- a/cov/cmdline/dup.c.func-sort-c.html +++ b/cov/cmdline/dup.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 diff --git a/cov/cmdline/dup.c.func.html b/cov/cmdline/dup.c.func.html index 1a267a3f..90e3eb0b 100644 --- a/cov/cmdline/dup.c.func.html +++ b/cov/cmdline/dup.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 diff --git a/cov/cmdline/dup.c.gcov.html b/cov/cmdline/dup.c.gcov.html index ce35360b..628d41b2 100644 --- a/cov/cmdline/dup.c.gcov.html +++ b/cov/cmdline/dup.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -168,14 +168,14 @@ 106 18 : struct snapraid_disk* disk = i->data; 107 : 108 : /* for each file */ - 109 16996 : for (j = disk->filelist; j != 0; j = j->next) { - 110 16978 : struct snapraid_file* file = j->data; + 109 16998 : for (j = disk->filelist; j != 0; j = j->next) { + 110 16980 : struct snapraid_file* file = j->data; 111 : struct snapraid_hash* hash; 112 : tommy_hash_t hash32; 113 : 114 : /* if empty, skip it */ - 115 16978 : if (file->size == 0) - 116 22 : continue; + 115 16980 : if (file->size == 0) + 116 24 : continue; 117 : 118 16956 : hash = hash_alloc(state, disk, file); 119 : diff --git a/cov/cmdline/elem.c.func-sort-c.html b/cov/cmdline/elem.c.func-sort-c.html index 6e20dd20..ad72c590 100644 --- a/cov/cmdline/elem.c.func-sort-c.html +++ b/cov/cmdline/elem.c.func-sort-c.html @@ -31,18 +31,18 @@ lcov.info Lines: - 537 - 574 - 93.6 % + 545 + 581 + 93.8 % Date: - 2015-11-13 + 2015-11-20 Functions: - 61 - 63 - 96.8 % + 62 + 64 + 96.9 % @@ -60,64 +60,68 @@ Hit count Sort by hit count - chunk_parity_inside_compare - 213182654 + chunk_parity_inside_compare + 211700412 - chunk_file_inside_compare - 123631586 + chunk_file_inside_compare + 123424429 - fs_par2file_get_ts - 62727960 + fs_file2block_get + 112904165 - fs_par2chunk_get_ts - 62657428 + fs_par2file_get_ts + 62671366 - fs_par2block_get_ts - 51081912 + fs_par2chunk_get_ts + 62562730 - chunk_file_compare - 43527266 + fs_par2block_get_ts + 51148943 - chunk_parity_compare - 43029334 + chunk_file_compare + 43527418 - fs_file2chunk_get_ts - 34130326 + chunk_parity_compare + 43029600 - fs_file2par_get_ts - 28966119 + fs_file2chunk_get_ts + 34157182 + + + fs_file2par_get_ts + 28740730 filter_apply - 12035121 + 12035450 - fs_allocate - 8850076 + fs_allocate + 8849850 file_block_size - 6609423 + 6610122 - chunk_file_check_foreach - 6291272 + chunk_file_check_foreach + 6291380 - chunk_parity_check_foreach - 6291272 + chunk_parity_check_foreach + 6291380 filter_recurse - 6023322 + 6023667 file_block_is_last @@ -125,95 +129,95 @@ chunk_alloc - 3607803 + 3607761 file_alloc - 3565018 + 3565141 - chunk_free - 3437425 + chunk_free + 3437520 file_free - 3417005 + 3417248 filter_element - 3226046 + 3226232 filter_path - 3223074 + 3223260 filter_content - 3066757 + 3066852 file_inode_compare_to_arg - 869924 + 866983 - time_compare - 713560 + time_compare + 743492 file_path_compare - 126320 + 126356 filter_type - 125579 + 125437 - link_alloc + link_alloc 115419 - link_free + link_free 109621 file_path_compare_to_arg - 105086 + 105104 - fs_deallocate - 104031 + fs_deallocate + 104155 filter_existence - 80649 - - - file_physical_compare - 54526 + 80654 file_name - 47858 + 47908 - chunk_disk_size_compare - 47777 + chunk_disk_size_compare + 47779 filter_correctness - 38803 + 38806 - link_name_compare_to_arg + file_physical_compare + 34618 + + + link_name_compare_to_arg 30380 file_namestamp_compare - 23929 + 23954 file_name_compare - 23929 + 23954 file_stamp_compare @@ -221,14 +225,14 @@ file_dup - 21784 + 21785 file_copy 6209 - disk_size + disk_size 3955 @@ -236,15 +240,15 @@ 2972 - fs_check + fs_check 2676 - disk_alloc + disk_alloc 1477 - map_alloc + map_alloc 1447 @@ -252,11 +256,11 @@ 1434 - disk_free + disk_free 1351 - map_free + map_free 1327 @@ -264,19 +268,19 @@ 1297 - link_alpha_compare + link_alpha_compare 1249 - disk_is_empty + disk_is_empty 804 - dir_alloc + dir_alloc 760 - dir_free + dir_free 712 @@ -288,7 +292,7 @@ 461 - dir_name_compare + dir_name_compare 217 @@ -296,7 +300,7 @@ 155 - chunk_disk_empty_compare + chunk_disk_empty_compare 10 diff --git a/cov/cmdline/elem.c.func.html b/cov/cmdline/elem.c.func.html index 14103d4a..a43507ef 100644 --- a/cov/cmdline/elem.c.func.html +++ b/cov/cmdline/elem.c.func.html @@ -31,18 +31,18 @@ lcov.info Lines: - 537 - 574 - 93.6 % + 545 + 581 + 93.8 % Date: - 2015-11-13 + 2015-11-20 Functions: - 61 - 63 - 96.8 % + 62 + 64 + 96.9 % @@ -61,43 +61,43 @@ chunk_alloc - 3607803 + 3607761 - chunk_disk_empty_compare + chunk_disk_empty_compare 10 - chunk_disk_size_compare - 47777 + chunk_disk_size_compare + 47779 - chunk_file_check_foreach - 6291272 + chunk_file_check_foreach + 6291380 - chunk_file_compare - 43527266 + chunk_file_compare + 43527418 - chunk_file_inside_compare - 123631586 + chunk_file_inside_compare + 123424429 - chunk_free - 3437425 + chunk_free + 3437520 - chunk_parity_check_foreach - 6291272 + chunk_parity_check_foreach + 6291380 - chunk_parity_compare - 43029334 + chunk_parity_compare + 43029600 - chunk_parity_inside_compare - 213182654 + chunk_parity_inside_compare + 211700412 content_alloc @@ -108,36 +108,36 @@ 1297 - dir_alloc + dir_alloc 760 - dir_free + dir_free 712 - dir_name_compare + dir_name_compare 217 - disk_alloc + disk_alloc 1477 - disk_free + disk_free 1351 - disk_is_empty + disk_is_empty 804 - disk_size + disk_size 3955 file_alloc - 3565018 + 3565141 file_block_is_last @@ -145,7 +145,7 @@ file_block_size - 6609423 + 6610122 file_copy @@ -153,11 +153,11 @@ file_dup - 21784 + 21785 file_free - 3417005 + 3417248 file_inode_compare @@ -165,27 +165,27 @@ file_inode_compare_to_arg - 869924 + 866983 file_name - 47858 + 47908 file_name_compare - 23929 + 23954 file_namestamp_compare - 23929 + 23954 file_path_compare - 126320 + 126356 file_path_compare_to_arg - 105086 + 105104 file_pathstamp_compare @@ -193,7 +193,7 @@ file_physical_compare - 54526 + 34618 file_rename @@ -213,15 +213,15 @@ filter_apply - 12035121 + 12035450 filter_content - 3066757 + 3066852 filter_correctness - 38803 + 38806 filter_dir @@ -229,11 +229,11 @@ filter_element - 3226046 + 3226232 filter_existence - 80649 + 80654 filter_free @@ -241,75 +241,79 @@ filter_path - 3223074 + 3223260 filter_recurse - 6023322 + 6023667 filter_type - 125579 + 125437 - fs_allocate - 8850076 + fs_allocate + 8849850 - fs_check + fs_check 2676 - fs_deallocate - 104031 + fs_deallocate + 104155 - fs_file2chunk_get_ts - 34130326 + fs_file2block_get + 112904165 - fs_file2par_get_ts - 28966119 + fs_file2chunk_get_ts + 34157182 - fs_par2block_get_ts - 51081912 + fs_file2par_get_ts + 28740730 - fs_par2chunk_get_ts - 62657428 + fs_par2block_get_ts + 51148943 - fs_par2file_get_ts - 62727960 + fs_par2chunk_get_ts + 62562730 - link_alloc + fs_par2file_get_ts + 62671366 + + + link_alloc 115419 - link_alpha_compare + link_alpha_compare 1249 - link_free + link_free 109621 - link_name_compare_to_arg + link_name_compare_to_arg 30380 - map_alloc + map_alloc 1447 - map_free + map_free 1327 - time_compare - 713560 + time_compare + 743492
diff --git a/cov/cmdline/elem.c.gcov.html b/cov/cmdline/elem.c.gcov.html index 75d2540a..0121811d 100644 --- a/cov/cmdline/elem.c.gcov.html +++ b/cov/cmdline/elem.c.gcov.html @@ -31,18 +31,18 @@ lcov.info Lines: - 537 - 574 - 93.6 % + 545 + 581 + 93.8 % Date: - 2015-11-13 + 2015-11-20 Functions: - 61 - 63 - 96.8 % + 62 + 64 + 96.9 % @@ -210,135 +210,135 @@ 148 461 : free(filter); 149 461 : } 150 : - 151 125579 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size) + 151 125437 : const char* filter_type(struct snapraid_filter* filter, char* out, size_t out_size) 152 : { 153 : const char* direction; - 154 125579 : if (filter->direction < 0) - 155 125333 : direction = "exclude"; + 154 125437 : if (filter->direction < 0) + 155 125191 : direction = "exclude"; 156 : else 157 246 : direction = "include"; 158 : - 159 125579 : if (filter->is_disk) + 159 125437 : if (filter->is_disk) 160 0 : pathprint(out, out_size, "%s %s:", direction, filter->pattern); - 161 125579 : else if (filter->is_dir) + 161 125437 : else if (filter->is_dir) 162 0 : pathprint(out, out_size, "%s %s/", direction, filter->pattern); 163 : else - 164 125579 : pathprint(out, out_size, "%s %s", direction, filter->pattern); + 164 125437 : pathprint(out, out_size, "%s %s", direction, filter->pattern); 165 : - 166 125579 : return out; + 166 125437 : return out; 167 : } 168 : - 169 12035121 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir) + 169 12035450 : static int filter_apply(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* path, const char* name, int is_dir) 170 : { - 171 12035121 : int ret = 0; + 171 12035450 : int ret = 0; 172 : 173 : /* match dirs with dirs and files with files */ - 174 12035121 : if (filter->is_dir && !is_dir) - 175 2938 : return 0; - 176 12032183 : if (!filter->is_dir && is_dir) - 177 6014696 : return 0; + 174 12035450 : if (filter->is_dir && !is_dir) + 175 2939 : return 0; + 176 12032511 : if (!filter->is_dir && is_dir) + 177 6014680 : return 0; 178 : - 179 6017487 : if (filter->is_path) { + 179 6017831 : if (filter->is_path) { 180 : /* skip initial slash, as always missing from the path */ - 181 2938 : if (fnmatch(filter->pattern + 1, path, FNM_PATHNAME | FNM_CASEINSENSITIVE_FOR_WIN) == 0) + 181 2939 : if (fnmatch(filter->pattern + 1, path, FNM_PATHNAME | FNM_CASEINSENSITIVE_FOR_WIN) == 0) 182 0 : ret = filter->direction; 183 : } else { - 184 6014549 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0) - 185 128077 : ret = filter->direction; + 184 6014892 : if (fnmatch(filter->pattern, name, FNM_CASEINSENSITIVE_FOR_WIN) == 0) + 185 127935 : ret = filter->direction; 186 : } 187 : - 188 6017487 : if (reason != 0 && ret < 0) - 189 125087 : *reason = filter; + 188 6017831 : if (reason != 0 && ret < 0) + 189 124945 : *reason = filter; 190 : - 191 6017487 : return ret; + 191 6017831 : return ret; 192 : } 193 : - 194 6023322 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir) + 194 6023667 : static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir) 195 : { 196 : char path[PATH_MAX]; 197 : char* name; 198 : unsigned i; 199 : - 200 6023322 : pathcpy(path, sizeof(path), const_path); + 200 6023667 : pathcpy(path, sizeof(path), const_path); 201 : 202 : /* filter for all the directories */ - 203 6023322 : name = path; - 204 86943549 : for (i = 0; path[i] != 0; ++i) { - 205 80923217 : if (path[i] == '/') { + 203 6023667 : name = path; + 204 86942366 : for (i = 0; path[i] != 0; ++i) { + 205 80921689 : if (path[i] == '/') { 206 : /* set a terminator */ - 207 6014789 : path[i] = 0; + 207 6014773 : path[i] = 0; 208 : 209 : /* filter the directory */ - 210 6014789 : if (filter_apply(filter, reason, path, name, 1) != 0) + 210 6014773 : if (filter_apply(filter, reason, path, name, 1) != 0) 211 2990 : return filter->direction; 212 : 213 : /* restore the slash */ - 214 6011799 : path[i] = '/'; + 214 6011783 : path[i] = '/'; 215 : 216 : /* next name */ - 217 6011799 : name = path + i + 1; + 217 6011783 : name = path + i + 1; 218 : } 219 : } 220 : 221 : /* filter the final file */ - 222 6020332 : if (filter_apply(filter, reason, path, name, is_dir) != 0) - 223 125087 : return filter->direction; + 222 6020677 : if (filter_apply(filter, reason, path, name, is_dir) != 0) + 223 124945 : return filter->direction; 224 : - 225 5895245 : return 0; + 225 5895732 : return 0; 226 : } 227 : - 228 3226046 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir) + 228 3226232 : static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir) 229 : { 230 : tommy_node* i; 231 : - 232 3226046 : int direction = 1; /* by default include all */ + 232 3226232 : int direction = 1; /* by default include all */ 233 : 234 : /* for each filter */ - 235 9222499 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) { + 235 9223179 : for (i = tommy_list_head(filterlist); i != 0; i = i->next) { 236 : int ret; - 237 6133199 : struct snapraid_filter* filter = i->data; + 237 6133552 : struct snapraid_filter* filter = i->data; 238 : - 239 6133199 : if (filter->is_disk) { - 240 109877 : if (fnmatch(filter->pattern, disk, FNM_CASEINSENSITIVE_FOR_WIN) == 0) - 241 8669 : ret = filter->direction; + 239 6133552 : if (filter->is_disk) { + 240 109885 : if (fnmatch(filter->pattern, disk, FNM_CASEINSENSITIVE_FOR_WIN) == 0) + 241 8670 : ret = filter->direction; 242 : else - 243 101208 : ret = 0; - 244 109877 : if (reason != 0 && ret < 0) + 243 101215 : ret = 0; + 244 109885 : if (reason != 0 && ret < 0) 245 0 : *reason = filter; 246 : } else { - 247 6023322 : ret = filter_recurse(filter, reason, sub, is_dir); + 247 6023667 : ret = filter_recurse(filter, reason, sub, is_dir); 248 : } 249 : - 250 6133199 : if (ret > 0) { + 250 6133552 : if (ret > 0) { 251 : /* include the file */ - 252 11659 : return 0; - 253 6121540 : } else if (ret < 0) { + 252 11660 : return 0; + 253 6121892 : } else if (ret < 0) { 254 : /* exclude the file */ - 255 125087 : return -1; + 255 124945 : return -1; 256 : } else { 257 : /* default is opposite of the last filter */ - 258 5996453 : direction = -filter->direction; - 259 5996453 : if (reason != 0 && direction < 0) - 260 3004264 : *reason = filter; + 258 5996947 : direction = -filter->direction; + 259 5996947 : if (reason != 0 && direction < 0) + 260 3004435 : *reason = filter; 261 : /* continue with the next one */ 262 : } 263 : } 264 : 265 : /* directories are always included by default, otherwise we cannot apply rules */ 266 : /* to the contained files */ - 267 3089300 : if (is_dir) + 267 3089627 : if (is_dir) 268 2971 : return 0; 269 : 270 : /* files are excluded/included depending of the last rule processed */ - 271 3086329 : if (direction < 0) - 272 57541 : return -1; + 271 3086656 : if (direction < 0) + 272 57545 : return -1; 273 : - 274 3028788 : return 0; + 274 3029111 : return 0; 275 : } 276 : - 277 3223074 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) + 277 3223260 : int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) 278 : { - 279 3223074 : return filter_element(filterlist, reason, disk, sub, 0); + 279 3223260 : return filter_element(filterlist, reason, disk, sub, 0); 280 : } 281 : 282 2972 : int filter_dir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) @@ -346,18 +346,18 @@ 284 2972 : return filter_element(filterlist, reason, disk, sub, 1); 285 : } 286 : - 287 80649 : int filter_existence(int filter_missing, const char* dir, const char* sub) + 287 80654 : int filter_existence(int filter_missing, const char* dir, const char* sub) 288 : { 289 : char path[PATH_MAX]; 290 : struct stat st; 291 : - 292 80649 : if (!filter_missing) - 293 34955 : return 0; + 292 80654 : if (!filter_missing) + 293 34958 : return 0; 294 : 295 : /* we directly check if in the disk the file is present or not */ - 296 45694 : pathprint(path, sizeof(path), "%s%s", dir, sub); + 296 45696 : pathprint(path, sizeof(path), "%s%s", dir, sub); 297 : - 298 45694 : if (lstat(path, &st) != 0) { + 298 45696 : if (lstat(path, &st) != 0) { 299 : /* if the file doesn't exist, we don't filter it out */ 300 5007 : if (errno == ENOENT) 301 5007 : return 0; @@ -368,111 +368,111 @@ 306 : } 307 : 308 : /* the file is present, so we filter it out */ - 309 40687 : return 1; + 309 40689 : return 1; 310 : } 311 : - 312 38803 : int filter_correctness(int filter_error, tommy_arrayblkof* infoarr, struct snapraid_disk* disk, struct snapraid_file* file) + 312 38806 : int filter_correctness(int filter_error, tommy_arrayblkof* infoarr, struct snapraid_disk* disk, struct snapraid_file* file) 313 : { 314 : unsigned i; 315 : - 316 38803 : if (!filter_error) - 317 16277 : return 0; + 316 38806 : if (!filter_error) + 317 16278 : return 0; 318 : 319 : /* check each block of the file */ - 320 60103 : for (i = 0; i < file->blockmax; ++i) { - 321 46031 : block_off_t parity_pos = fs_file2par_get(disk, file, i); - 322 46031 : snapraid_info info = info_get(infoarr, parity_pos); + 320 60231 : for (i = 0; i < file->blockmax; ++i) { + 321 46123 : block_off_t parity_pos = fs_file2par_get(disk, file, i); + 322 46123 : snapraid_info info = info_get(infoarr, parity_pos); 323 : 324 : /* if the file has a bad block, don't exclude it */ - 325 46031 : if (info_get_bad(info)) - 326 8454 : return 0; + 325 46123 : if (info_get_bad(info)) + 326 8420 : return 0; 327 : } 328 : 329 : /* the file is correct, so we filter it out */ - 330 14072 : return 1; + 330 14108 : return 1; 331 : } 332 : - 333 3066757 : int filter_content(tommy_list* contentlist, const char* path) + 333 3066852 : int filter_content(tommy_list* contentlist, const char* path) 334 : { 335 : tommy_node* i; 336 : - 337 39679746 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) { - 338 16773116 : struct snapraid_content* content = i->data; + 337 39681406 : for (i = tommy_list_head(contentlist); i != 0; i = i->next) { + 338 16773851 : struct snapraid_content* content = i->data; 339 : char tmp[PATH_MAX]; 340 : - 341 16773116 : if (pathcmp(content->content, path) == 0) + 341 16773851 : if (pathcmp(content->content, path) == 0) 342 0 : return -1; 343 : 344 : /* exclude also the ".tmp" copy used to save it */ - 345 16773116 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); - 346 16773116 : if (pathcmp(tmp, path) == 0) + 345 16773851 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); + 346 16773851 : if (pathcmp(tmp, path) == 0) 347 0 : return -1; 348 : 349 : /* exclude also the ".lock" file */ - 350 16773116 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content); - 351 16773116 : if (pathcmp(tmp, path) == 0) + 350 16773851 : pathprint(tmp, sizeof(tmp), "%s.lock", content->content); + 351 16773851 : if (pathcmp(tmp, path) == 0) 352 0 : return -1; 353 : } 354 : - 355 3066757 : return 0; + 355 3066852 : return 0; 356 : } 357 : - 358 3565018 : struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical) + 358 3565141 : struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical) 359 : { 360 : struct snapraid_file* file; 361 : block_off_t i; 362 : - 363 3565018 : file = malloc_nofail(sizeof(struct snapraid_file)); - 364 3565018 : file->sub = strdup_nofail(sub); - 365 3565018 : file->size = size; - 366 3565018 : file->blockmax = (size + block_size - 1) / block_size; - 367 3565018 : file->mtime_sec = mtime_sec; - 368 3565018 : file->mtime_nsec = mtime_nsec; - 369 3565018 : file->inode = inode; - 370 3565018 : file->physical = physical; - 371 3565018 : file->flag = 0; - 372 3565018 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block)); + 363 3565141 : file = malloc_nofail(sizeof(struct snapraid_file)); + 364 3565141 : file->sub = strdup_nofail(sub); + 365 3565141 : file->size = size; + 366 3565141 : file->blockmax = (size + block_size - 1) / block_size; + 367 3565141 : file->mtime_sec = mtime_sec; + 368 3565141 : file->mtime_nsec = mtime_nsec; + 369 3565141 : file->inode = inode; + 370 3565141 : file->physical = physical; + 371 3565141 : file->flag = 0; + 372 3565141 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block)); 373 : - 374 12361466 : for (i = 0; i < file->blockmax; ++i) { - 375 8796448 : block_state_set(&file->blockvec[i], BLOCK_STATE_CHG); - 376 8796448 : hash_invalid_set(file->blockvec[i].hash); + 374 12361356 : for (i = 0; i < file->blockmax; ++i) { + 375 8796215 : block_state_set(&file->blockvec[i], BLOCK_STATE_CHG); + 376 8796215 : hash_invalid_set(file->blockvec[i].hash); 377 : } 378 : - 379 3565018 : return file; + 379 3565141 : return file; 380 : } 381 : - 382 21784 : struct snapraid_file* file_dup(struct snapraid_file* copy) + 382 21785 : struct snapraid_file* file_dup(struct snapraid_file* copy) 383 : { 384 : struct snapraid_file* file; 385 : block_off_t i; 386 : - 387 21784 : file = malloc_nofail(sizeof(struct snapraid_file)); - 388 21784 : file->sub = strdup_nofail(copy->sub); - 389 21784 : file->size = copy->size; - 390 21784 : file->blockmax = copy->blockmax; - 391 21784 : file->mtime_sec = copy->mtime_sec; - 392 21784 : file->mtime_nsec = copy->mtime_nsec; - 393 21784 : file->inode = copy->inode; - 394 21784 : file->physical = copy->physical; - 395 21784 : file->flag = copy->flag; - 396 21784 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block)); + 387 21785 : file = malloc_nofail(sizeof(struct snapraid_file)); + 388 21785 : file->sub = strdup_nofail(copy->sub); + 389 21785 : file->size = copy->size; + 390 21785 : file->blockmax = copy->blockmax; + 391 21785 : file->mtime_sec = copy->mtime_sec; + 392 21785 : file->mtime_nsec = copy->mtime_nsec; + 393 21785 : file->inode = copy->inode; + 394 21785 : file->physical = copy->physical; + 395 21785 : file->flag = copy->flag; + 396 21785 : file->blockvec = malloc_nofail(file->blockmax * sizeof(struct snapraid_block)); 397 : - 398 75416 : for (i = 0; i < file->blockmax; ++i) { - 399 53632 : file->blockvec[i].state = copy->blockvec[i].state; - 400 53632 : memcpy(file->blockvec[i].hash, copy->blockvec[i].hash, HASH_SIZE); + 398 75420 : for (i = 0; i < file->blockmax; ++i) { + 399 53635 : file->blockvec[i].state = copy->blockvec[i].state; + 400 53635 : memcpy(file->blockvec[i].hash, copy->blockvec[i].hash, HASH_SIZE); 401 : } 402 : - 403 21784 : return file; + 403 21785 : return file; 404 : } 405 : - 406 3417005 : void file_free(struct snapraid_file* file) + 406 3417248 : void file_free(struct snapraid_file* file) 407 : { - 408 3417005 : free(file->sub); - 409 3417005 : file->sub = 0; - 410 3417005 : free(file->blockvec); - 411 3417005 : file->blockvec = 0; - 412 3417005 : free(file); - 413 3417005 : } + 408 3417248 : free(file->sub); + 409 3417248 : file->sub = 0; + 410 3417248 : free(file->blockvec); + 411 3417248 : file->blockvec = 0; + 412 3417248 : free(file); + 413 3417248 : } 414 : 415 155 : void file_rename(struct snapraid_file* file, const char* sub) 416 : { @@ -516,31 +516,31 @@ 454 6209 : file_flag_set(dst_file, FILE_IS_COPY); 455 6209 : } 456 : - 457 47858 : const char* file_name(const struct snapraid_file* file) + 457 47908 : const char* file_name(const struct snapraid_file* file) 458 : { - 459 47858 : const char* r = strrchr(file->sub, '/'); + 459 47908 : const char* r = strrchr(file->sub, '/'); 460 : - 461 47858 : if (!r) + 461 47908 : if (!r) 462 8 : r = file->sub; 463 : else - 464 47850 : ++r; - 465 47858 : return r; + 464 47900 : ++r; + 465 47908 : return r; 466 : } 467 : - 468 6609423 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size) + 468 6610122 : unsigned file_block_size(struct snapraid_file* file, block_off_t file_pos, unsigned block_size) 469 : { 470 : /* if it's the last block */ - 471 6609423 : if (file_pos + 1 == file->blockmax) { + 471 6610122 : if (file_pos + 1 == file->blockmax) { 472 : unsigned block_remainder; - 473 2692095 : if (file->size == 0) + 473 2692717 : if (file->size == 0) 474 0 : return 0; - 475 2692095 : block_remainder = file->size % block_size; - 476 2692095 : if (block_remainder == 0) - 477 1567 : block_remainder = block_size; - 478 2692095 : return block_remainder; + 475 2692717 : block_remainder = file->size % block_size; + 476 2692717 : if (block_remainder == 0) + 477 1544 : block_remainder = block_size; + 478 2692717 : return block_remainder; 479 : } 480 : - 481 3917328 : return block_size; + 481 3917405 : return block_size; 482 : } 483 : 484 5319910 : int file_block_is_last(struct snapraid_file* file, block_off_t file_pos) @@ -558,16 +558,16 @@ 496 5319910 : return file_pos == file->blockmax - 1; 497 : } 498 : - 499 869924 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data) + 499 866983 : int file_inode_compare_to_arg(const void* void_arg, const void* void_data) 500 : { - 501 869924 : const uint64_t* arg = void_arg; - 502 869924 : const struct snapraid_file* file = void_data; + 501 866983 : const uint64_t* arg = void_arg; + 502 866983 : const struct snapraid_file* file = void_data; 503 : - 504 869924 : if (*arg < file->inode) + 504 866983 : if (*arg < file->inode) 505 0 : return -1; - 506 869924 : if (*arg > file->inode) + 506 866983 : if (*arg > file->inode) 507 0 : return 1; - 508 869924 : return 0; + 508 866983 : return 0; 509 : } 510 : 511 0 : int file_inode_compare(const void* void_a, const void* void_b) @@ -582,42 +582,42 @@ 520 0 : return 0; 521 : } 522 : - 523 126320 : int file_path_compare(const void* void_a, const void* void_b) + 523 126356 : int file_path_compare(const void* void_a, const void* void_b) 524 : { - 525 126320 : const struct snapraid_file* file_a = void_a; - 526 126320 : const struct snapraid_file* file_b = void_b; + 525 126356 : const struct snapraid_file* file_a = void_a; + 526 126356 : const struct snapraid_file* file_b = void_b; 527 : - 528 126320 : return strcmp(file_a->sub, file_b->sub); + 528 126356 : return strcmp(file_a->sub, file_b->sub); 529 : } 530 : - 531 54526 : int file_physical_compare(const void* void_a, const void* void_b) + 531 34618 : int file_physical_compare(const void* void_a, const void* void_b) 532 : { - 533 54526 : const struct snapraid_file* file_a = void_a; - 534 54526 : const struct snapraid_file* file_b = void_b; + 533 34618 : const struct snapraid_file* file_a = void_a; + 534 34618 : const struct snapraid_file* file_b = void_b; 535 : - 536 54526 : if (file_a->physical < file_b->physical) - 537 35814 : return -1; - 538 18712 : if (file_a->physical > file_b->physical) - 539 18712 : return 1; - 540 0 : return 0; + 536 34618 : if (file_a->physical < file_b->physical) + 537 26412 : return -1; + 538 8206 : if (file_a->physical > file_b->physical) + 539 8204 : return 1; + 540 2 : return 0; 541 : } 542 : - 543 105086 : int file_path_compare_to_arg(const void* void_arg, const void* void_data) + 543 105104 : int file_path_compare_to_arg(const void* void_arg, const void* void_data) 544 : { - 545 105086 : const char* arg = void_arg; - 546 105086 : const struct snapraid_file* file = void_data; + 545 105104 : const char* arg = void_arg; + 546 105104 : const struct snapraid_file* file = void_data; 547 : - 548 105086 : return strcmp(arg, file->sub); + 548 105104 : return strcmp(arg, file->sub); 549 : } 550 : - 551 23929 : int file_name_compare(const void* void_a, const void* void_b) + 551 23954 : int file_name_compare(const void* void_a, const void* void_b) 552 : { - 553 23929 : const struct snapraid_file* file_a = void_a; - 554 23929 : const struct snapraid_file* file_b = void_b; - 555 23929 : const char* name_a = file_name(file_a); - 556 23929 : const char* name_b = file_name(file_b); + 553 23954 : const struct snapraid_file* file_a = void_a; + 554 23954 : const struct snapraid_file* file_b = void_b; + 555 23954 : const char* name_a = file_name(file_a); + 556 23954 : const char* name_b = file_name(file_b); 557 : - 558 23929 : return strcmp(name_a, name_b); + 558 23954 : return strcmp(name_a, name_b); 559 : } 560 : 561 23659 : int file_stamp_compare(const void* void_a, const void* void_b) @@ -643,13 +643,13 @@ 581 23659 : return 0; 582 : } 583 : - 584 23929 : int file_namestamp_compare(const void* void_a, const void* void_b) + 584 23954 : int file_namestamp_compare(const void* void_a, const void* void_b) 585 : { 586 : int ret; 587 : - 588 23929 : ret = file_name_compare(void_a, void_b); - 589 23929 : if (ret != 0) - 590 270 : return ret; + 588 23954 : ret = file_name_compare(void_a, void_b); + 589 23954 : if (ret != 0) + 590 295 : return ret; 591 : 592 23659 : return file_stamp_compare(void_a, void_b); 593 : } @@ -665,697 +665,740 @@ 603 0 : return file_stamp_compare(void_a, void_b); 604 : } 605 : - 606 3607803 : struct snapraid_chunk* chunk_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count) + 606 3607761 : struct snapraid_chunk* chunk_alloc(block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos, block_off_t count) 607 : { 608 : struct snapraid_chunk* chunk; 609 : - 610 3607803 : chunk = malloc_nofail(sizeof(struct snapraid_chunk)); - 611 3607803 : chunk->parity_pos = parity_pos; - 612 3607803 : chunk->file = file; - 613 3607803 : chunk->file_pos = file_pos; - 614 3607803 : chunk->count = count; - 615 : - 616 3607803 : return chunk; - 617 : } - 618 : - 619 3437425 : void chunk_free(struct snapraid_chunk* chunk) - 620 : { - 621 3437425 : free(chunk); - 622 3437425 : } - 623 : - 624 43029334 : int chunk_parity_compare(const void* void_a, const void* void_b) - 625 : { - 626 43029334 : const struct snapraid_chunk* arg_a = void_a; - 627 43029334 : const struct snapraid_chunk* arg_b = void_b; + 610 3607761 : if (count == 0) { + 611 : /* LCOV_EXCL_START */ + 612 : log_fatal("Internal inconsistency when allocating empty chunk for file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax); + 613 : exit(EXIT_FAILURE); + 614 : /* LCOV_EXCL_STOP */ + 615 : } + 616 3607761 : if (file_pos + count > file->blockmax) { + 617 : /* LCOV_EXCL_START */ + 618 : log_fatal("Internal inconsistency when allocating overflowing chunk for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax); + 619 : exit(EXIT_FAILURE); + 620 : /* LCOV_EXCL_STOP */ + 621 : } + 622 : + 623 3607761 : chunk = malloc_nofail(sizeof(struct snapraid_chunk)); + 624 3607761 : chunk->parity_pos = parity_pos; + 625 3607761 : chunk->file = file; + 626 3607761 : chunk->file_pos = file_pos; + 627 3607761 : chunk->count = count; 628 : - 629 43029334 : if (arg_a->parity_pos < arg_b->parity_pos) - 630 931264 : return -1; - 631 42098070 : if (arg_a->parity_pos > arg_b->parity_pos) - 632 42059274 : return 1; - 633 : - 634 38796 : return 0; - 635 : } + 629 3607761 : return chunk; + 630 : } + 631 : + 632 3437520 : void chunk_free(struct snapraid_chunk* chunk) + 633 : { + 634 3437520 : free(chunk); + 635 3437520 : } 636 : - 637 43527266 : int chunk_file_compare(const void* void_a, const void* void_b) + 637 43029600 : int chunk_parity_compare(const void* void_a, const void* void_b) 638 : { - 639 43527266 : const struct snapraid_chunk* arg_a = void_a; - 640 43527266 : const struct snapraid_chunk* arg_b = void_b; + 639 43029600 : const struct snapraid_chunk* arg_a = void_a; + 640 43029600 : const struct snapraid_chunk* arg_b = void_b; 641 : - 642 43527266 : if (arg_a->file < arg_b->file) - 643 855502 : return -1; - 644 42671764 : if (arg_a->file > arg_b->file) - 645 42603010 : return 1; + 642 43029600 : if (arg_a->parity_pos < arg_b->parity_pos) + 643 932908 : return -1; + 644 42096692 : if (arg_a->parity_pos > arg_b->parity_pos) + 645 42057855 : return 1; 646 : - 647 68754 : if (arg_a->file_pos < arg_b->file_pos) - 648 192 : return -1; - 649 68562 : if (arg_a->file_pos > arg_b->file_pos) - 650 29766 : return 1; - 651 : - 652 38796 : return 0; - 653 : } + 647 38837 : return 0; + 648 : } + 649 : + 650 43527418 : int chunk_file_compare(const void* void_a, const void* void_b) + 651 : { + 652 43527418 : const struct snapraid_chunk* arg_a = void_a; + 653 43527418 : const struct snapraid_chunk* arg_b = void_b; 654 : - 655 115419 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag) - 656 : { - 657 : struct snapraid_link* slink; - 658 : - 659 115419 : slink = malloc_nofail(sizeof(struct snapraid_link)); - 660 115419 : slink->sub = strdup_nofail(sub); - 661 115419 : slink->linkto = strdup_nofail(linkto); - 662 115419 : slink->flag = link_flag; - 663 : - 664 115419 : return slink; - 665 : } - 666 : - 667 109621 : void link_free(struct snapraid_link* slink) - 668 : { - 669 109621 : free(slink->sub); - 670 109621 : free(slink->linkto); - 671 109621 : free(slink); - 672 109621 : } - 673 : - 674 30380 : int link_name_compare_to_arg(const void* void_arg, const void* void_data) - 675 : { - 676 30380 : const char* arg = void_arg; - 677 30380 : const struct snapraid_link* slink = void_data; - 678 : - 679 30380 : return strcmp(arg, slink->sub); - 680 : } - 681 : - 682 1249 : int link_alpha_compare(const void* void_a, const void* void_b) - 683 : { - 684 1249 : const struct snapraid_link* slink_a = void_a; - 685 1249 : const struct snapraid_link* slink_b = void_b; + 655 43527418 : if (arg_a->file < arg_b->file) + 656 856585 : return -1; + 657 42670833 : if (arg_a->file > arg_b->file) + 658 42601978 : return 1; + 659 : + 660 68855 : if (arg_a->file_pos < arg_b->file_pos) + 661 192 : return -1; + 662 68663 : if (arg_a->file_pos > arg_b->file_pos) + 663 29826 : return 1; + 664 : + 665 38837 : return 0; + 666 : } + 667 : + 668 115419 : struct snapraid_link* link_alloc(const char* sub, const char* linkto, unsigned link_flag) + 669 : { + 670 : struct snapraid_link* slink; + 671 : + 672 115419 : slink = malloc_nofail(sizeof(struct snapraid_link)); + 673 115419 : slink->sub = strdup_nofail(sub); + 674 115419 : slink->linkto = strdup_nofail(linkto); + 675 115419 : slink->flag = link_flag; + 676 : + 677 115419 : return slink; + 678 : } + 679 : + 680 109621 : void link_free(struct snapraid_link* slink) + 681 : { + 682 109621 : free(slink->sub); + 683 109621 : free(slink->linkto); + 684 109621 : free(slink); + 685 109621 : } 686 : - 687 1249 : return strcmp(slink_a->sub, slink_b->sub); - 688 : } - 689 : - 690 760 : struct snapraid_dir* dir_alloc(const char* sub) - 691 : { - 692 : struct snapraid_dir* dir; - 693 : - 694 760 : dir = malloc_nofail(sizeof(struct snapraid_dir)); - 695 760 : dir->sub = strdup_nofail(sub); - 696 760 : dir->flag = 0; - 697 : - 698 760 : return dir; - 699 : } - 700 : - 701 712 : void dir_free(struct snapraid_dir* dir) - 702 : { - 703 712 : free(dir->sub); - 704 712 : free(dir); - 705 712 : } + 687 30380 : int link_name_compare_to_arg(const void* void_arg, const void* void_data) + 688 : { + 689 30380 : const char* arg = void_arg; + 690 30380 : const struct snapraid_link* slink = void_data; + 691 : + 692 30380 : return strcmp(arg, slink->sub); + 693 : } + 694 : + 695 1249 : int link_alpha_compare(const void* void_a, const void* void_b) + 696 : { + 697 1249 : const struct snapraid_link* slink_a = void_a; + 698 1249 : const struct snapraid_link* slink_b = void_b; + 699 : + 700 1249 : return strcmp(slink_a->sub, slink_b->sub); + 701 : } + 702 : + 703 760 : struct snapraid_dir* dir_alloc(const char* sub) + 704 : { + 705 : struct snapraid_dir* dir; 706 : - 707 217 : int dir_name_compare(const void* void_arg, const void* void_data) - 708 : { - 709 217 : const char* arg = void_arg; - 710 217 : const struct snapraid_dir* dir = void_data; - 711 : - 712 217 : return strcmp(arg, dir->sub); - 713 : } - 714 : - 715 1477 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip) - 716 : { - 717 : struct snapraid_disk* disk; - 718 : - 719 1477 : disk = malloc_nofail(sizeof(struct snapraid_disk)); - 720 1477 : pathcpy(disk->name, sizeof(disk->name), name); - 721 1477 : pathimport(disk->dir, sizeof(disk->dir), dir); - 722 : - 723 : /* ensure that the dir terminate with "/" if it isn't empty */ - 724 1477 : pathslash(disk->dir, sizeof(disk->dir)); - 725 : - 726 1477 : disk->smartctl[0] = 0; - 727 1477 : disk->device = dev; - 728 1477 : disk->tick = 0; - 729 1477 : disk->total_blocks = 0; - 730 1477 : disk->free_blocks = 0; - 731 1477 : disk->first_free_block = 0; - 732 1477 : disk->has_volatile_inodes = 0; - 733 1477 : disk->has_unreliable_physical = 0; - 734 1477 : disk->has_different_uuid = 0; - 735 1477 : disk->has_unsupported_uuid = 0; - 736 1477 : disk->had_empty_uuid = 0; - 737 1477 : disk->mapping_idx = -1; - 738 1477 : disk->skip_access = skip; - 739 1477 : tommy_list_init(&disk->filelist); - 740 1477 : tommy_list_init(&disk->deletedlist); - 741 1477 : tommy_hashdyn_init(&disk->inodeset); - 742 1477 : tommy_hashdyn_init(&disk->pathset); - 743 1477 : tommy_hashdyn_init(&disk->stampset); - 744 1477 : tommy_list_init(&disk->linklist); - 745 1477 : tommy_hashdyn_init(&disk->linkset); - 746 1477 : tommy_list_init(&disk->dirlist); - 747 1477 : tommy_hashdyn_init(&disk->dirset); - 748 1477 : tommy_tree_init(&disk->fs_parity, chunk_parity_compare); - 749 1477 : tommy_tree_init(&disk->fs_file, chunk_file_compare); - 750 1477 : disk->fs_last = 0; - 751 : - 752 1477 : return disk; - 753 : } - 754 : - 755 1351 : void disk_free(struct snapraid_disk* disk) - 756 : { - 757 1351 : tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free); - 758 1351 : tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free); - 759 1351 : tommy_tree_foreach(&disk->fs_file, (tommy_foreach_func*)chunk_free); - 760 1351 : tommy_hashdyn_done(&disk->inodeset); - 761 1351 : tommy_hashdyn_done(&disk->pathset); - 762 1351 : tommy_hashdyn_done(&disk->stampset); - 763 1351 : tommy_list_foreach(&disk->linklist, (tommy_foreach_func*)link_free); - 764 1351 : tommy_hashdyn_done(&disk->linkset); - 765 1351 : tommy_list_foreach(&disk->dirlist, (tommy_foreach_func*)dir_free); - 766 1351 : tommy_hashdyn_done(&disk->dirset); - 767 1351 : free(disk); - 768 1351 : } - 769 : - 770 : struct chunk_disk_empty { - 771 : block_off_t blockmax; - 772 : }; - 773 : - 774 : /** - 775 : * Compare the chunk if inside the specified blockmax. - 776 : */ - 777 10 : static int chunk_disk_empty_compare(const void* void_a, const void* void_b) - 778 : { - 779 10 : const struct chunk_disk_empty* arg_a = void_a; - 780 10 : const struct snapraid_chunk* arg_b = void_b; - 781 : - 782 : /* if the block is inside the specified blockmax, it's found */ - 783 10 : if (arg_a->blockmax > arg_b->parity_pos) - 784 5 : return 0; - 785 : - 786 : /* otherwise search for a smaller one */ - 787 5 : return -1; - 788 : } - 789 : - 790 804 : int disk_is_empty(struct snapraid_disk* disk, block_off_t blockmax) + 707 760 : dir = malloc_nofail(sizeof(struct snapraid_dir)); + 708 760 : dir->sub = strdup_nofail(sub); + 709 760 : dir->flag = 0; + 710 : + 711 760 : return dir; + 712 : } + 713 : + 714 712 : void dir_free(struct snapraid_dir* dir) + 715 : { + 716 712 : free(dir->sub); + 717 712 : free(dir); + 718 712 : } + 719 : + 720 217 : int dir_name_compare(const void* void_arg, const void* void_data) + 721 : { + 722 217 : const char* arg = void_arg; + 723 217 : const struct snapraid_dir* dir = void_data; + 724 : + 725 217 : return strcmp(arg, dir->sub); + 726 : } + 727 : + 728 1477 : struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip) + 729 : { + 730 : struct snapraid_disk* disk; + 731 : + 732 1477 : disk = malloc_nofail(sizeof(struct snapraid_disk)); + 733 1477 : pathcpy(disk->name, sizeof(disk->name), name); + 734 1477 : pathimport(disk->dir, sizeof(disk->dir), dir); + 735 : + 736 : /* ensure that the dir terminate with "/" if it isn't empty */ + 737 1477 : pathslash(disk->dir, sizeof(disk->dir)); + 738 : + 739 1477 : disk->smartctl[0] = 0; + 740 1477 : disk->device = dev; + 741 1477 : disk->tick = 0; + 742 1477 : disk->total_blocks = 0; + 743 1477 : disk->free_blocks = 0; + 744 1477 : disk->first_free_block = 0; + 745 1477 : disk->has_volatile_inodes = 0; + 746 1477 : disk->has_unreliable_physical = 0; + 747 1477 : disk->has_different_uuid = 0; + 748 1477 : disk->has_unsupported_uuid = 0; + 749 1477 : disk->had_empty_uuid = 0; + 750 1477 : disk->mapping_idx = -1; + 751 1477 : disk->skip_access = skip; + 752 1477 : tommy_list_init(&disk->filelist); + 753 1477 : tommy_list_init(&disk->deletedlist); + 754 1477 : tommy_hashdyn_init(&disk->inodeset); + 755 1477 : tommy_hashdyn_init(&disk->pathset); + 756 1477 : tommy_hashdyn_init(&disk->stampset); + 757 1477 : tommy_list_init(&disk->linklist); + 758 1477 : tommy_hashdyn_init(&disk->linkset); + 759 1477 : tommy_list_init(&disk->dirlist); + 760 1477 : tommy_hashdyn_init(&disk->dirset); + 761 1477 : tommy_tree_init(&disk->fs_parity, chunk_parity_compare); + 762 1477 : tommy_tree_init(&disk->fs_file, chunk_file_compare); + 763 1477 : disk->fs_last = 0; + 764 : + 765 1477 : return disk; + 766 : } + 767 : + 768 1351 : void disk_free(struct snapraid_disk* disk) + 769 : { + 770 1351 : tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free); + 771 1351 : tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free); + 772 1351 : tommy_tree_foreach(&disk->fs_file, (tommy_foreach_func*)chunk_free); + 773 1351 : tommy_hashdyn_done(&disk->inodeset); + 774 1351 : tommy_hashdyn_done(&disk->pathset); + 775 1351 : tommy_hashdyn_done(&disk->stampset); + 776 1351 : tommy_list_foreach(&disk->linklist, (tommy_foreach_func*)link_free); + 777 1351 : tommy_hashdyn_done(&disk->linkset); + 778 1351 : tommy_list_foreach(&disk->dirlist, (tommy_foreach_func*)dir_free); + 779 1351 : tommy_hashdyn_done(&disk->dirset); + 780 1351 : free(disk); + 781 1351 : } + 782 : + 783 : struct chunk_disk_empty { + 784 : block_off_t blockmax; + 785 : }; + 786 : + 787 : /** + 788 : * Compare the chunk if inside the specified blockmax. + 789 : */ + 790 10 : static int chunk_disk_empty_compare(const void* void_a, const void* void_b) 791 : { - 792 804 : struct chunk_disk_empty arg = { blockmax }; - 793 : - 794 : /* if there is an element, it's not empty */ - 795 : /* even if links and dirs have no block allocation */ - 796 804 : if (!tommy_list_empty(&disk->filelist)) - 797 736 : return 0; - 798 68 : if (!tommy_list_empty(&disk->linklist)) - 799 0 : return 0; - 800 68 : if (!tommy_list_empty(&disk->dirlist)) - 801 0 : return 0; + 792 10 : const struct chunk_disk_empty* arg_a = void_a; + 793 10 : const struct snapraid_chunk* arg_b = void_b; + 794 : + 795 : /* if the block is inside the specified blockmax, it's found */ + 796 10 : if (arg_a->blockmax > arg_b->parity_pos) + 797 5 : return 0; + 798 : + 799 : /* otherwise search for a smaller one */ + 800 5 : return -1; + 801 : } 802 : - 803 : /* search for any chunk inside blockmax */ - 804 68 : if (tommy_tree_search_compare(&disk->fs_parity, chunk_disk_empty_compare, &arg) != 0) - 805 5 : return 0; + 803 804 : int disk_is_empty(struct snapraid_disk* disk, block_off_t blockmax) + 804 : { + 805 804 : struct chunk_disk_empty arg = { blockmax }; 806 : - 807 : /* finally, it's empty */ - 808 63 : return 1; - 809 : } - 810 : - 811 : struct chunk_disk_size { - 812 : block_off_t size; - 813 : }; - 814 : - 815 : /** - 816 : * Compare the chunk by highest parity position. - 817 : * - 818 : * The maximum parity position is stored as size. - 819 : */ - 820 47777 : static int chunk_disk_size_compare(const void* void_a, const void* void_b) - 821 : { - 822 47777 : struct chunk_disk_size* arg_a = (void*)void_a; - 823 47777 : const struct snapraid_chunk* arg_b = void_b; - 824 : - 825 : /* get the maximum size */ - 826 47777 : if (arg_a->size < arg_b->parity_pos + arg_b->count) - 827 47777 : arg_a->size = arg_b->parity_pos + arg_b->count; - 828 : - 829 : /* search always for a bigger one */ - 830 47777 : return 1; - 831 : } - 832 : - 833 3955 : block_off_t disk_size(struct snapraid_disk* disk) + 807 : /* if there is an element, it's not empty */ + 808 : /* even if links and dirs have no block allocation */ + 809 804 : if (!tommy_list_empty(&disk->filelist)) + 810 736 : return 0; + 811 68 : if (!tommy_list_empty(&disk->linklist)) + 812 0 : return 0; + 813 68 : if (!tommy_list_empty(&disk->dirlist)) + 814 0 : return 0; + 815 : + 816 : /* search for any chunk inside blockmax */ + 817 68 : if (tommy_tree_search_compare(&disk->fs_parity, chunk_disk_empty_compare, &arg) != 0) + 818 5 : return 0; + 819 : + 820 : /* finally, it's empty */ + 821 63 : return 1; + 822 : } + 823 : + 824 : struct chunk_disk_size { + 825 : block_off_t size; + 826 : }; + 827 : + 828 : /** + 829 : * Compare the chunk by highest parity position. + 830 : * + 831 : * The maximum parity position is stored as size. + 832 : */ + 833 47779 : static int chunk_disk_size_compare(const void* void_a, const void* void_b) 834 : { - 835 3955 : struct chunk_disk_size arg = { 0 }; - 836 3955 : tommy_tree_search_compare(&disk->fs_parity, chunk_disk_size_compare, &arg); - 837 3955 : return arg.size; - 838 : } - 839 : - 840 : struct chunk_check { - 841 : const struct snapraid_chunk* prev; - 842 : int result; - 843 : }; - 844 : - 845 6291272 : void chunk_parity_check_foreach(void* void_arg, void* void_obj) - 846 : { - 847 6291272 : struct chunk_check* arg = void_arg; - 848 6291272 : const struct snapraid_chunk* obj = void_obj; - 849 6291272 : const struct snapraid_chunk* prev = arg->prev; - 850 : - 851 : /* set the next previous block */ - 852 6291272 : arg->prev = obj; - 853 : - 854 : /* stop reporting if too many errors */ - 855 6291272 : if (arg->result > 100) { - 856 : /* LCOV_EXCL_START */ - 857 : return; - 858 : /* LCOV_EXCL_STOP */ - 859 : } - 860 : - 861 : /* check only if there is a previous block */ - 862 6291272 : if (!prev) - 863 2473 : return; - 864 : - 865 : /* check the order */ - 866 6288799 : if (prev->parity_pos >= obj->parity_pos) { - 867 : /* LCOV_EXCL_START */ - 868 : log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n", - 869 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count); - 870 : ++arg->result; - 871 : return; - 872 : /* LCOV_EXCL_STOP */ - 873 : } - 874 : - 875 : /* check that the chunks don't overlap */ - 876 6288799 : if (prev->parity_pos + prev->count > obj->parity_pos) { - 877 : /* LCOV_EXCL_START */ - 878 : log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n", - 879 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count); - 880 : ++arg->result; - 881 : return; - 882 : /* LCOV_EXCL_STOP */ - 883 : } - 884 : } - 885 : - 886 6291272 : void chunk_file_check_foreach(void* void_arg, void* void_obj) - 887 : { - 888 6291272 : struct chunk_check* arg = void_arg; - 889 6291272 : const struct snapraid_chunk* obj = void_obj; - 890 6291272 : const struct snapraid_chunk* prev = arg->prev; - 891 : - 892 : /* set the next previous block */ - 893 6291272 : arg->prev = obj; - 894 : - 895 : /* stop reporting if too many errors */ - 896 6291272 : if (arg->result > 100) { - 897 : /* LCOV_EXCL_START */ - 898 : return; - 899 : /* LCOV_EXCL_STOP */ - 900 : } - 901 : - 902 : /* note that for deleted files, some chunks may be missing */ - 903 : - 904 : /* if the files are different */ - 905 6291272 : if (!prev || prev->file != obj->file) { - 906 6247390 : if (prev != 0) { - 907 6244917 : if (file_flag_has(prev->file, FILE_IS_DELETED)) { - 908 : /* check that the chunk doesn't overflow the file */ - 909 59701 : if (prev->file_pos + prev->count > prev->file->blockmax) { - 910 : /* LCOV_EXCL_START */ - 911 : log_fatal("Internal inconsistency in delete end for file '%s' at '%u:%u' overflowing size '%u'\n", - 912 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax); - 913 : ++arg->result; - 914 : return; - 915 : /* LCOV_EXCL_STOP */ - 916 : } - 917 : } else { - 918 : /* check that the chunk ends the file */ - 919 6185216 : if (prev->file_pos + prev->count != prev->file->blockmax) { - 920 : /* LCOV_EXCL_START */ - 921 : log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n", - 922 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax); - 923 : ++arg->result; - 924 : return; - 925 : /* LCOV_EXCL_STOP */ - 926 : } - 927 : } - 928 : } - 929 : - 930 12494780 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { - 931 : /* check that the chunk doesn't overflow the file */ - 932 59776 : if (obj->file_pos + obj->count > obj->file->blockmax) { - 933 : /* LCOV_EXCL_START */ - 934 : log_fatal("Internal inconsistency in delete start for file '%s' at '%u:%u' overflowing size '%u'\n", - 935 : obj->file->sub, obj->file_pos, obj->count, obj->file->blockmax); - 936 : ++arg->result; - 937 : return; - 938 : /* LCOV_EXCL_STOP */ - 939 : } - 940 : } else { - 941 : /* check that the chunk starts the file */ - 942 6187614 : if (obj->file_pos != 0) { - 943 : /* LCOV_EXCL_START */ - 944 : log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n", - 945 : obj->file->sub, obj->file_pos, obj->count); - 946 : ++arg->result; - 947 : return; - 948 : /* LCOV_EXCL_STOP */ - 949 : } - 950 : } - 951 : } else { - 952 : /* check the order */ - 953 43882 : if (prev->file_pos >= obj->file_pos) { - 954 : /* LCOV_EXCL_START */ - 955 : log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n", - 956 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); - 957 : ++arg->result; - 958 : return; - 959 : /* LCOV_EXCL_STOP */ - 960 : } - 961 : - 962 43882 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { - 963 : /* check that the chunks don't overlap */ - 964 27 : if (prev->file_pos + prev->count > obj->file_pos) { - 965 : /* LCOV_EXCL_START */ - 966 : log_fatal("Internal inconsistency in delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n", - 967 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); - 968 : ++arg->result; - 969 : return; - 970 : /* LCOV_EXCL_STOP */ - 971 : } - 972 : } else { - 973 : /* check that the chunks are sequential */ - 974 43855 : if (prev->file_pos + prev->count != obj->file_pos) { - 975 : /* LCOV_EXCL_START */ - 976 : log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n", - 977 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); - 978 : ++arg->result; - 979 : return; - 980 : /* LCOV_EXCL_STOP */ - 981 : } - 982 : } - 983 : } - 984 : } - 985 : - 986 2676 : int fs_check(struct snapraid_disk* disk) - 987 : { - 988 : struct chunk_check arg; - 989 : - 990 : /* error count starts from 0 */ - 991 2676 : arg.result = 0; + 835 47779 : struct chunk_disk_size* arg_a = (void*)void_a; + 836 47779 : const struct snapraid_chunk* arg_b = void_b; + 837 : + 838 : /* get the maximum size */ + 839 47779 : if (arg_a->size < arg_b->parity_pos + arg_b->count) + 840 47779 : arg_a->size = arg_b->parity_pos + arg_b->count; + 841 : + 842 : /* search always for a bigger one */ + 843 47779 : return 1; + 844 : } + 845 : + 846 3955 : block_off_t disk_size(struct snapraid_disk* disk) + 847 : { + 848 3955 : struct chunk_disk_size arg = { 0 }; + 849 3955 : tommy_tree_search_compare(&disk->fs_parity, chunk_disk_size_compare, &arg); + 850 3955 : return arg.size; + 851 : } + 852 : + 853 : struct chunk_check { + 854 : const struct snapraid_chunk* prev; + 855 : int result; + 856 : }; + 857 : + 858 6291380 : void chunk_parity_check_foreach(void* void_arg, void* void_obj) + 859 : { + 860 6291380 : struct chunk_check* arg = void_arg; + 861 6291380 : const struct snapraid_chunk* obj = void_obj; + 862 6291380 : const struct snapraid_chunk* prev = arg->prev; + 863 : + 864 : /* set the next previous block */ + 865 6291380 : arg->prev = obj; + 866 : + 867 : /* stop reporting if too many errors */ + 868 6291380 : if (arg->result > 100) { + 869 : /* LCOV_EXCL_START */ + 870 : return; + 871 : /* LCOV_EXCL_STOP */ + 872 : } + 873 : + 874 6291380 : if (obj->count == 0) { + 875 : /* LCOV_EXCL_START */ + 876 : log_fatal("Internal inconsistency in parity count zero for file '%s' at '%u'\n", + 877 : obj->file->sub, obj->parity_pos); + 878 : ++arg->result; + 879 : return; + 880 : /* LCOV_EXCL_STOP */ + 881 : } + 882 : + 883 : /* check only if there is a previous block */ + 884 6291380 : if (!prev) + 885 2473 : return; + 886 : + 887 : /* check the order */ + 888 6288907 : if (prev->parity_pos >= obj->parity_pos) { + 889 : /* LCOV_EXCL_START */ + 890 : log_fatal("Internal inconsistency in parity order for files '%s' at '%u:%u' and '%s' at '%u:%u'\n", + 891 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count); + 892 : ++arg->result; + 893 : return; + 894 : /* LCOV_EXCL_STOP */ + 895 : } + 896 : + 897 : /* check that the chunks don't overlap */ + 898 6288907 : if (prev->parity_pos + prev->count > obj->parity_pos) { + 899 : /* LCOV_EXCL_START */ + 900 : log_fatal("Internal inconsistency for parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n", + 901 : prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count); + 902 : ++arg->result; + 903 : return; + 904 : /* LCOV_EXCL_STOP */ + 905 : } + 906 : } + 907 : + 908 6291380 : void chunk_file_check_foreach(void* void_arg, void* void_obj) + 909 : { + 910 6291380 : struct chunk_check* arg = void_arg; + 911 6291380 : const struct snapraid_chunk* obj = void_obj; + 912 6291380 : const struct snapraid_chunk* prev = arg->prev; + 913 : + 914 : /* set the next previous block */ + 915 6291380 : arg->prev = obj; + 916 : + 917 : /* stop reporting if too many errors */ + 918 6291380 : if (arg->result > 100) { + 919 : /* LCOV_EXCL_START */ + 920 : return; + 921 : /* LCOV_EXCL_STOP */ + 922 : } + 923 : + 924 6291380 : if (obj->count == 0) { + 925 : /* LCOV_EXCL_START */ + 926 : log_fatal("Internal inconsistency in file count zero for file '%s' at '%u'\n", + 927 : obj->file->sub, obj->file_pos); + 928 : ++arg->result; + 929 : return; + 930 : /* LCOV_EXCL_STOP */ + 931 : } + 932 : + 933 : /* note that for deleted files, some chunks may be missing */ + 934 : + 935 : /* if the files are different */ + 936 6291380 : if (!prev || prev->file != obj->file) { + 937 6247390 : if (prev != 0) { + 938 6244917 : if (file_flag_has(prev->file, FILE_IS_DELETED)) { + 939 : /* check that the chunk doesn't overflow the file */ + 940 59701 : if (prev->file_pos + prev->count > prev->file->blockmax) { + 941 : /* LCOV_EXCL_START */ + 942 : log_fatal("Internal inconsistency in delete end for file '%s' at '%u:%u' overflowing size '%u'\n", + 943 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax); + 944 : ++arg->result; + 945 : return; + 946 : /* LCOV_EXCL_STOP */ + 947 : } + 948 : } else { + 949 : /* check that the chunk ends the file */ + 950 6185216 : if (prev->file_pos + prev->count != prev->file->blockmax) { + 951 : /* LCOV_EXCL_START */ + 952 : log_fatal("Internal inconsistency in file end for file '%s' at '%u:%u' instead of size '%u'\n", + 953 : prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax); + 954 : ++arg->result; + 955 : return; + 956 : /* LCOV_EXCL_STOP */ + 957 : } + 958 : } + 959 : } + 960 : + 961 12494780 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { + 962 : /* check that the chunk doesn't overflow the file */ + 963 59776 : if (obj->file_pos + obj->count > obj->file->blockmax) { + 964 : /* LCOV_EXCL_START */ + 965 : log_fatal("Internal inconsistency in delete start for file '%s' at '%u:%u' overflowing size '%u'\n", + 966 : obj->file->sub, obj->file_pos, obj->count, obj->file->blockmax); + 967 : ++arg->result; + 968 : return; + 969 : /* LCOV_EXCL_STOP */ + 970 : } + 971 : } else { + 972 : /* check that the chunk starts the file */ + 973 6187614 : if (obj->file_pos != 0) { + 974 : /* LCOV_EXCL_START */ + 975 : log_fatal("Internal inconsistency in file start for file '%s' at '%u:%u'\n", + 976 : obj->file->sub, obj->file_pos, obj->count); + 977 : ++arg->result; + 978 : return; + 979 : /* LCOV_EXCL_STOP */ + 980 : } + 981 : } + 982 : } else { + 983 : /* check the order */ + 984 43990 : if (prev->file_pos >= obj->file_pos) { + 985 : /* LCOV_EXCL_START */ + 986 : log_fatal("Internal inconsistency in file order for file '%s' at '%u:%u' and at '%u:%u'\n", + 987 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); + 988 : ++arg->result; + 989 : return; + 990 : /* LCOV_EXCL_STOP */ + 991 : } 992 : - 993 : /* check parity sequence */ - 994 2676 : arg.prev = 0; - 995 2676 : tommy_tree_foreach_arg(&disk->fs_parity, chunk_parity_check_foreach, &arg); - 996 : - 997 : /* check file sequence */ - 998 2676 : arg.prev = 0; - 999 2676 : tommy_tree_foreach_arg(&disk->fs_file, chunk_file_check_foreach, &arg); - 1000 : - 1001 2676 : if (arg.result != 0) - 1002 0 : return -1; - 1003 : - 1004 2676 : return 0; - 1005 : } - 1006 : - 1007 : struct chunk_parity_inside { - 1008 : block_off_t parity_pos; - 1009 : }; - 1010 : - 1011 : /** - 1012 : * Compare the chunk if containing the specified parity position. - 1013 : */ - 1014 213182654 : static int chunk_parity_inside_compare(const void* void_a, const void* void_b) - 1015 : { - 1016 213182654 : const struct chunk_parity_inside* arg_a = void_a; - 1017 213182654 : const struct snapraid_chunk* arg_b = void_b; - 1018 : - 1019 213182654 : if (arg_a->parity_pos < arg_b->parity_pos) - 1020 79586474 : return -1; - 1021 133596180 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count) - 1022 116201011 : return 1; + 993 43990 : if (file_flag_has(obj->file, FILE_IS_DELETED)) { + 994 : /* check that the chunks don't overlap */ + 995 27 : if (prev->file_pos + prev->count > obj->file_pos) { + 996 : /* LCOV_EXCL_START */ + 997 : log_fatal("Internal inconsistency in delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n", + 998 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); + 999 : ++arg->result; + 1000 : return; + 1001 : /* LCOV_EXCL_STOP */ + 1002 : } + 1003 : } else { + 1004 : /* check that the chunks are sequential */ + 1005 43963 : if (prev->file_pos + prev->count != obj->file_pos) { + 1006 : /* LCOV_EXCL_START */ + 1007 : log_fatal("Internal inconsistency in file sequence for file '%s' at '%u:%u' and at '%u:%u'\n", + 1008 : prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count); + 1009 : ++arg->result; + 1010 : return; + 1011 : /* LCOV_EXCL_STOP */ + 1012 : } + 1013 : } + 1014 : } + 1015 : } + 1016 : + 1017 2676 : int fs_check(struct snapraid_disk* disk) + 1018 : { + 1019 : struct chunk_check arg; + 1020 : + 1021 : /* error count starts from 0 */ + 1022 2676 : arg.result = 0; 1023 : - 1024 17395169 : return 0; - 1025 : } - 1026 : - 1027 : /** - 1028 : * Seach the chunk at the specified parity position. - 1029 : * The search is optimized for sequential accesses. - 1030 : * \return If not found return 0 - 1031 : */ - 1032 62657428 : static struct snapraid_chunk* fs_par2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos) - 1033 : { - 1034 : struct snapraid_chunk* chunk; - 1035 : - 1036 : /* check if the last accessed chunk matches */ - 1037 62657428 : if (*fs_last - 1038 62843273 : && parity_pos >= (*fs_last)->parity_pos - 1039 62738070 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count - 1040 : ) { - 1041 43160159 : chunk = *fs_last; - 1042 : } else { - 1043 19497269 : struct chunk_parity_inside arg = { parity_pos }; - 1044 19497269 : chunk = tommy_tree_search_compare(&disk->fs_parity, chunk_parity_inside_compare, &arg); - 1045 : } - 1046 : - 1047 62844816 : if (!chunk) - 1048 2353186 : return 0; + 1024 : /* check parity sequence */ + 1025 2676 : arg.prev = 0; + 1026 2676 : tommy_tree_foreach_arg(&disk->fs_parity, chunk_parity_check_foreach, &arg); + 1027 : + 1028 : /* check file sequence */ + 1029 2676 : arg.prev = 0; + 1030 2676 : tommy_tree_foreach_arg(&disk->fs_file, chunk_file_check_foreach, &arg); + 1031 : + 1032 2676 : if (arg.result != 0) + 1033 0 : return -1; + 1034 : + 1035 2676 : return 0; + 1036 : } + 1037 : + 1038 : struct chunk_parity_inside { + 1039 : block_off_t parity_pos; + 1040 : }; + 1041 : + 1042 : /** + 1043 : * Compare the chunk if containing the specified parity position. + 1044 : */ + 1045 211700412 : static int chunk_parity_inside_compare(const void* void_a, const void* void_b) + 1046 : { + 1047 211700412 : const struct chunk_parity_inside* arg_a = void_a; + 1048 211700412 : const struct snapraid_chunk* arg_b = void_b; 1049 : - 1050 : /* store the last accessed chunk */ - 1051 60491630 : *fs_last = chunk; - 1052 : - 1053 60491630 : return chunk; - 1054 : } - 1055 : - 1056 : struct chunk_file_inside { - 1057 : struct snapraid_file* file; - 1058 : block_off_t file_pos; - 1059 : }; - 1060 : - 1061 : /** - 1062 : * Compare the chunk if containing the specified file position. - 1063 : */ - 1064 123631586 : static int chunk_file_inside_compare(const void* void_a, const void* void_b) - 1065 : { - 1066 123631586 : const struct chunk_file_inside* arg_a = void_a; - 1067 123631586 : const struct snapraid_chunk* arg_b = void_b; - 1068 : - 1069 123631586 : if (arg_a->file < arg_b->file) - 1070 52889679 : return -1; - 1071 70741907 : if (arg_a->file > arg_b->file) - 1072 58811856 : return 1; - 1073 : - 1074 11930051 : if (arg_a->file_pos < arg_b->file_pos) - 1075 48627 : return -1; - 1076 11881424 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count) - 1077 44495 : return 1; - 1078 : - 1079 11836929 : return 0; - 1080 : } - 1081 : - 1082 : /** - 1083 : * Seach the chunk at the specified file position. - 1084 : * The search is optimized for sequential accesses. - 1085 : * \return If not found return 0 - 1086 : */ - 1087 34130326 : static struct snapraid_chunk* fs_file2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos) - 1088 : { - 1089 : struct snapraid_chunk* chunk; - 1090 : - 1091 : /* check if the last accessed chunk matches */ - 1092 34130326 : if (*fs_last - 1093 34328656 : && file == (*fs_last)->file - 1094 22569402 : && file_pos >= (*fs_last)->file_pos - 1095 22577024 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count - 1096 : ) { - 1097 22445049 : chunk = *fs_last; - 1098 : } else { - 1099 11685277 : struct chunk_file_inside arg = { file, file_pos }; - 1100 11685277 : chunk = tommy_tree_search_compare(&disk->fs_file, chunk_file_inside_compare, &arg); - 1101 : } - 1102 : - 1103 34258963 : if (!chunk) - 1104 0 : return 0; - 1105 : - 1106 : /* store the last accessed chunk */ - 1107 34258963 : *fs_last = chunk; - 1108 : - 1109 34258963 : return chunk; - 1110 : } - 1111 : - 1112 62727960 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos) - 1113 : { - 1114 : struct snapraid_chunk* chunk; - 1115 : - 1116 62727960 : chunk = fs_par2chunk_get_ts(disk, fs_last, parity_pos); - 1117 62761969 : if (!chunk) - 1118 2353128 : return 0; - 1119 : - 1120 60408841 : if (file_pos) - 1121 59975482 : *file_pos = chunk->file_pos + (parity_pos - chunk->parity_pos); - 1122 : - 1123 60408841 : return chunk->file; - 1124 : } - 1125 : - 1126 28966119 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos) - 1127 : { - 1128 : struct snapraid_chunk* chunk; - 1129 : - 1130 28966119 : chunk = fs_file2chunk_get_ts(disk, fs_last, file, file_pos); - 1131 28884994 : if (!chunk) { - 1132 : /* LCOV_EXCL_START */ - 1133 : log_fatal("Internal inconsistency when resolving file '%s' at position '%u' in disk '%s'\n", file->sub, file_pos, disk->name); - 1134 : exit(EXIT_FAILURE); - 1135 : /* LCOV_EXCL_STOP */ - 1136 : } - 1137 : - 1138 28884994 : return chunk->parity_pos + (file_pos - chunk->file_pos); - 1139 : } - 1140 : - 1141 8850076 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos) - 1142 : { - 1143 : struct snapraid_chunk* chunk; - 1144 : struct snapraid_chunk* parity_chunk; - 1145 : struct snapraid_chunk* file_chunk; + 1050 211700412 : if (arg_a->parity_pos < arg_b->parity_pos) + 1051 78963776 : return -1; + 1052 132736636 : if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count) + 1053 115362811 : return 1; + 1054 : + 1055 17373825 : return 0; + 1056 : } + 1057 : + 1058 : /** + 1059 : * Seach the chunk at the specified parity position. + 1060 : * The search is optimized for sequential accesses. + 1061 : * \return If not found return 0 + 1062 : */ + 1063 62562730 : static struct snapraid_chunk* fs_par2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos) + 1064 : { + 1065 : struct snapraid_chunk* chunk; + 1066 : + 1067 : /* check if the last accessed chunk matches */ + 1068 62562730 : if (*fs_last + 1069 62828537 : && parity_pos >= (*fs_last)->parity_pos + 1070 62678201 : && parity_pos < (*fs_last)->parity_pos + (*fs_last)->count + 1071 : ) { + 1072 43113171 : chunk = *fs_last; + 1073 : } else { + 1074 19449559 : struct chunk_parity_inside arg = { parity_pos }; + 1075 19449559 : chunk = tommy_tree_search_compare(&disk->fs_parity, chunk_parity_inside_compare, &arg); + 1076 : } + 1077 : + 1078 62800800 : if (!chunk) + 1079 2351363 : return 0; + 1080 : + 1081 : /* store the last accessed chunk */ + 1082 60449437 : *fs_last = chunk; + 1083 : + 1084 60449437 : return chunk; + 1085 : } + 1086 : + 1087 : struct chunk_file_inside { + 1088 : struct snapraid_file* file; + 1089 : block_off_t file_pos; + 1090 : }; + 1091 : + 1092 : /** + 1093 : * Compare the chunk if containing the specified file position. + 1094 : */ + 1095 123424429 : static int chunk_file_inside_compare(const void* void_a, const void* void_b) + 1096 : { + 1097 123424429 : const struct chunk_file_inside* arg_a = void_a; + 1098 123424429 : const struct snapraid_chunk* arg_b = void_b; + 1099 : + 1100 123424429 : if (arg_a->file < arg_b->file) + 1101 52876931 : return -1; + 1102 70547498 : if (arg_a->file > arg_b->file) + 1103 58630297 : return 1; + 1104 : + 1105 11917201 : if (arg_a->file_pos < arg_b->file_pos) + 1106 49120 : return -1; + 1107 11868081 : if (arg_a->file_pos >= arg_b->file_pos + arg_b->count) + 1108 44006 : return 1; + 1109 : + 1110 11824075 : return 0; + 1111 : } + 1112 : + 1113 : /** + 1114 : * Seach the chunk at the specified file position. + 1115 : * The search is optimized for sequential accesses. + 1116 : * \return If not found return 0 + 1117 : */ + 1118 34157182 : static struct snapraid_chunk* fs_file2chunk_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos) + 1119 : { + 1120 : struct snapraid_chunk* chunk; + 1121 : + 1122 : /* check if the last accessed chunk matches */ + 1123 34157182 : if (*fs_last + 1124 34107260 : && file == (*fs_last)->file + 1125 22496891 : && file_pos >= (*fs_last)->file_pos + 1126 22481340 : && file_pos < (*fs_last)->file_pos + (*fs_last)->count + 1127 : ) { + 1128 22376150 : chunk = *fs_last; + 1129 : } else { + 1130 11781032 : struct chunk_file_inside arg = { file, file_pos }; + 1131 11781032 : chunk = tommy_tree_search_compare(&disk->fs_file, chunk_file_inside_compare, &arg); + 1132 : } + 1133 : + 1134 34132437 : if (!chunk) + 1135 0 : return 0; + 1136 : + 1137 : /* store the last accessed chunk */ + 1138 34132437 : *fs_last = chunk; + 1139 : + 1140 34132437 : return chunk; + 1141 : } + 1142 : + 1143 62671366 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos) + 1144 : { + 1145 : struct snapraid_chunk* chunk; 1146 : - 1147 8850076 : if (file_pos > 0) { - 1148 : /* search an existing chunk for the previous file_pos */ - 1149 5267929 : chunk = fs_file2chunk_get_ts(disk, &disk->fs_last, file, file_pos - 1); + 1147 62671366 : chunk = fs_par2chunk_get_ts(disk, fs_last, parity_pos); + 1148 62750330 : if (!chunk) + 1149 2351221 : return 0; 1150 : - 1151 5267929 : if (chunk != 0 && parity_pos == chunk->parity_pos + chunk->count) { - 1152 : /* ensure that we are extending the chunk at the end */ - 1153 5242274 : if (file_pos != chunk->file_pos + chunk->count) { - 1154 : /* LCOV_EXCL_START */ - 1155 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u' in the middle of chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, chunk->file_pos, chunk->count, disk->name); - 1156 : exit(EXIT_FAILURE); - 1157 : /* LCOV_EXCL_STOP */ - 1158 : } - 1159 : - 1160 : /* extend the existing chunk */ - 1161 5242274 : ++chunk->count; - 1162 : - 1163 14092350 : return; - 1164 : } - 1165 : } - 1166 : - 1167 : /* a chunk doesn't exist, and we have to create a new one */ - 1168 3607802 : chunk = chunk_alloc(parity_pos, file, file_pos, 1); - 1169 : - 1170 : /* insert the chunk in the trees */ - 1171 3607802 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &chunk->parity_node, chunk); - 1172 3607802 : file_chunk = tommy_tree_insert(&disk->fs_file, &chunk->file_node, chunk); - 1173 : - 1174 3607802 : if (parity_chunk != chunk || file_chunk != chunk) { - 1175 : /* LCOV_EXCL_START */ - 1176 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u' for existing chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, chunk->file_pos, chunk->count, disk->name); - 1177 : exit(EXIT_FAILURE); - 1178 : /* LCOV_EXCL_STOP */ - 1179 : } - 1180 : - 1181 : /* store the last accessed chunk */ - 1182 3607802 : disk->fs_last = chunk; - 1183 : } - 1184 : - 1185 104031 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos) - 1186 : { - 1187 : struct snapraid_chunk* chunk; - 1188 : struct snapraid_chunk* second_chunk; - 1189 : struct snapraid_chunk* parity_chunk; - 1190 : struct snapraid_chunk* file_chunk; - 1191 : block_off_t first_count, second_count; - 1192 : - 1193 104031 : chunk = fs_par2chunk_get_ts(disk, &disk->fs_last, parity_pos); - 1194 104031 : if (!chunk) { - 1195 : /* LCOV_EXCL_START */ - 1196 : log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing chunk in disk '%s'\n", parity_pos, disk->name); - 1197 : exit(EXIT_FAILURE); - 1198 : /* LCOV_EXCL_STOP */ - 1199 : } + 1151 60399109 : if (file_pos) + 1152 59839728 : *file_pos = chunk->file_pos + (parity_pos - chunk->parity_pos); + 1153 : + 1154 60399109 : return chunk->file; + 1155 : } + 1156 : + 1157 28740730 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos) + 1158 : { + 1159 : struct snapraid_chunk* chunk; + 1160 : + 1161 28740730 : chunk = fs_file2chunk_get_ts(disk, fs_last, file, file_pos); + 1162 28850478 : if (!chunk) { + 1163 : /* LCOV_EXCL_START */ + 1164 : log_fatal("Internal inconsistency when resolving file '%s' at position '%u/%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, disk->name); + 1165 : exit(EXIT_FAILURE); + 1166 : /* LCOV_EXCL_STOP */ + 1167 : } + 1168 : + 1169 28850478 : return chunk->parity_pos + (file_pos - chunk->file_pos); + 1170 : } + 1171 : + 1172 8849850 : void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snapraid_file* file, block_off_t file_pos) + 1173 : { + 1174 : struct snapraid_chunk* chunk; + 1175 : struct snapraid_chunk* parity_chunk; + 1176 : struct snapraid_chunk* file_chunk; + 1177 : + 1178 8849850 : if (file_pos > 0) { + 1179 : /* search an existing chunk for the previous file_pos */ + 1180 5267799 : chunk = fs_file2chunk_get_ts(disk, &disk->fs_last, file, file_pos - 1); + 1181 : + 1182 5267799 : if (chunk != 0 && parity_pos == chunk->parity_pos + chunk->count) { + 1183 : /* ensure that we are extending the chunk at the end */ + 1184 5242090 : if (file_pos != chunk->file_pos + chunk->count) { + 1185 : /* LCOV_EXCL_START */ + 1186 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' in the middle of chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, chunk->file_pos, chunk->count, disk->name); + 1187 : exit(EXIT_FAILURE); + 1188 : /* LCOV_EXCL_STOP */ + 1189 : } + 1190 : + 1191 : /* extend the existing chunk */ + 1192 5242090 : ++chunk->count; + 1193 : + 1194 14091940 : return; + 1195 : } + 1196 : } + 1197 : + 1198 : /* a chunk doesn't exist, and we have to create a new one */ + 1199 3607760 : chunk = chunk_alloc(parity_pos, file, file_pos, 1); 1200 : - 1201 : /* if it's the only block of the chunk, delete it */ - 1202 104031 : if (chunk->count == 1) { - 1203 : /* remove from the trees */ - 1204 38796 : tommy_tree_remove(&disk->fs_parity, chunk); - 1205 38796 : tommy_tree_remove(&disk->fs_file, chunk); - 1206 : - 1207 : /* deallocate */ - 1208 38796 : chunk_free(chunk); - 1209 : - 1210 : /* clear the last accessed chunk */ - 1211 38796 : disk->fs_last = 0; - 1212 38796 : return; - 1213 : } - 1214 : - 1215 : /* if it's at the start of the chunk, shrink the chunk */ - 1216 65235 : if (parity_pos == chunk->parity_pos) { - 1217 65233 : ++chunk->parity_pos; - 1218 65233 : ++chunk->file_pos; - 1219 65233 : --chunk->count; - 1220 65233 : return; - 1221 : } - 1222 : - 1223 : /* if it's at the end of the chunk, shrink the chunk */ - 1224 2 : if (parity_pos == chunk->parity_pos + chunk->count - 1) { - 1225 1 : --chunk->count; - 1226 1 : return; - 1227 : } - 1228 : - 1229 : /* otherwise it's in the middle */ - 1230 1 : first_count = parity_pos - chunk->parity_pos; - 1231 1 : second_count = chunk->count - first_count - 1; - 1232 : - 1233 : /* adjust the first chunk */ - 1234 1 : chunk->count = first_count; - 1235 : - 1236 : /* allocate the second chunk */ - 1237 1 : second_chunk = chunk_alloc(chunk->parity_pos + first_count + 1, chunk->file, chunk->file_pos + first_count + 1, second_count); - 1238 : - 1239 : /* insert the chunk in the trees */ - 1240 1 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &second_chunk->parity_node, second_chunk); - 1241 1 : file_chunk = tommy_tree_insert(&disk->fs_file, &second_chunk->file_node, second_chunk); - 1242 : - 1243 1 : if (parity_chunk != second_chunk || file_chunk != second_chunk) { - 1244 : /* LCOV_EXCL_START */ - 1245 : log_fatal("Internal inconsistency when deallocating parity position '%u' for splitting chunk '%u:%u' in disk '%s'\n", parity_pos, second_chunk->file_pos, second_chunk->count, disk->name); - 1246 : exit(EXIT_FAILURE); - 1247 : /* LCOV_EXCL_STOP */ - 1248 : } - 1249 : - 1250 : /* store the last accessed chunk */ - 1251 1 : disk->fs_last = second_chunk; - 1252 : } + 1201 : /* insert the chunk in the trees */ + 1202 3607760 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &chunk->parity_node, chunk); + 1203 3607760 : file_chunk = tommy_tree_insert(&disk->fs_file, &chunk->file_node, chunk); + 1204 : + 1205 3607760 : if (parity_chunk != chunk || file_chunk != chunk) { + 1206 : /* LCOV_EXCL_START */ + 1207 : log_fatal("Internal inconsistency when allocating file '%s' at position '%u/%u' for existing chunk '%u:%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, chunk->file_pos, chunk->count, disk->name); + 1208 : exit(EXIT_FAILURE); + 1209 : /* LCOV_EXCL_STOP */ + 1210 : } + 1211 : + 1212 : /* store the last accessed chunk */ + 1213 3607760 : disk->fs_last = chunk; + 1214 : } + 1215 : + 1216 104155 : void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos) + 1217 : { + 1218 : struct snapraid_chunk* chunk; + 1219 : struct snapraid_chunk* second_chunk; + 1220 : struct snapraid_chunk* parity_chunk; + 1221 : struct snapraid_chunk* file_chunk; + 1222 : block_off_t first_count, second_count; + 1223 : + 1224 104155 : chunk = fs_par2chunk_get_ts(disk, &disk->fs_last, parity_pos); + 1225 104155 : if (!chunk) { + 1226 : /* LCOV_EXCL_START */ + 1227 : log_fatal("Internal inconsistency when deallocating parity position '%u' for not existing chunk in disk '%s'\n", parity_pos, disk->name); + 1228 : exit(EXIT_FAILURE); + 1229 : /* LCOV_EXCL_STOP */ + 1230 : } + 1231 : + 1232 : /* if it's the only block of the chunk, delete it */ + 1233 104155 : if (chunk->count == 1) { + 1234 : /* remove from the trees */ + 1235 38837 : tommy_tree_remove(&disk->fs_parity, chunk); + 1236 38837 : tommy_tree_remove(&disk->fs_file, chunk); + 1237 : + 1238 : /* deallocate */ + 1239 38837 : chunk_free(chunk); + 1240 : + 1241 : /* clear the last accessed chunk */ + 1242 38837 : disk->fs_last = 0; + 1243 38837 : return; + 1244 : } + 1245 : + 1246 : /* if it's at the start of the chunk, shrink the chunk */ + 1247 65318 : if (parity_pos == chunk->parity_pos) { + 1248 65316 : ++chunk->parity_pos; + 1249 65316 : ++chunk->file_pos; + 1250 65316 : --chunk->count; + 1251 65316 : return; + 1252 : } 1253 : - 1254 51081912 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos) - 1255 : { - 1256 : struct snapraid_file* file; - 1257 : block_off_t file_pos; - 1258 : - 1259 51081912 : file = fs_par2file_get_ts(disk, fs_last, parity_pos, &file_pos); - 1260 : - 1261 51089852 : if (!file) - 1262 2353186 : return BLOCK_EMPTY; + 1254 : /* if it's at the end of the chunk, shrink the chunk */ + 1255 2 : if (parity_pos == chunk->parity_pos + chunk->count - 1) { + 1256 1 : --chunk->count; + 1257 1 : return; + 1258 : } + 1259 : + 1260 : /* otherwise it's in the middle */ + 1261 1 : first_count = parity_pos - chunk->parity_pos; + 1262 1 : second_count = chunk->count - first_count - 1; 1263 : - 1264 48736666 : return fs_file2block_get(file, file_pos); - 1265 : } + 1264 : /* adjust the first chunk */ + 1265 1 : chunk->count = first_count; 1266 : - 1267 1447 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid) - 1268 : { - 1269 : struct snapraid_map* map; - 1270 : - 1271 1447 : map = malloc_nofail(sizeof(struct snapraid_map)); - 1272 1447 : pathcpy(map->name, sizeof(map->name), name); - 1273 1447 : map->position = position; - 1274 1447 : map->total_blocks = total_blocks; - 1275 1447 : map->free_blocks = free_blocks; - 1276 1447 : pathcpy(map->uuid, sizeof(map->uuid), uuid); - 1277 : - 1278 1447 : return map; - 1279 : } + 1267 : /* allocate the second chunk */ + 1268 1 : second_chunk = chunk_alloc(chunk->parity_pos + first_count + 1, chunk->file, chunk->file_pos + first_count + 1, second_count); + 1269 : + 1270 : /* insert the chunk in the trees */ + 1271 1 : parity_chunk = tommy_tree_insert(&disk->fs_parity, &second_chunk->parity_node, second_chunk); + 1272 1 : file_chunk = tommy_tree_insert(&disk->fs_file, &second_chunk->file_node, second_chunk); + 1273 : + 1274 1 : if (parity_chunk != second_chunk || file_chunk != second_chunk) { + 1275 : /* LCOV_EXCL_START */ + 1276 : log_fatal("Internal inconsistency when deallocating parity position '%u' for splitting chunk '%u:%u' in disk '%s'\n", parity_pos, second_chunk->file_pos, second_chunk->count, disk->name); + 1277 : exit(EXIT_FAILURE); + 1278 : /* LCOV_EXCL_STOP */ + 1279 : } 1280 : - 1281 1327 : void map_free(struct snapraid_map* map) - 1282 : { - 1283 1327 : free(map); - 1284 1327 : } - 1285 : - 1286 713560 : int time_compare(const void* void_a, const void* void_b) - 1287 : { - 1288 713560 : const time_t* time_a = void_a; - 1289 713560 : const time_t* time_b = void_b; - 1290 : - 1291 713560 : if (*time_a < *time_b) - 1292 26114 : return -1; - 1293 687446 : if (*time_a > *time_b) - 1294 154206 : return 1; - 1295 533240 : return 0; - 1296 : } + 1281 : /* store the last accessed chunk */ + 1282 1 : disk->fs_last = second_chunk; + 1283 : } + 1284 : + 1285 112904165 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos) + 1286 : { + 1287 112904165 : if (file_pos >= file->blockmax) { + 1288 : /* LCOV_EXCL_START */ + 1289 : log_fatal("Internal inconsistency when dereferencing file '%s' at position '%u/%u'\n", file->sub, file_pos, file->blockmax); + 1290 : exit(EXIT_FAILURE); + 1291 : /* LCOV_EXCL_STOP */ + 1292 : } + 1293 : + 1294 112904165 : return &file->blockvec[file_pos]; + 1295 : } + 1296 : + 1297 51148943 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos) + 1298 : { + 1299 : struct snapraid_file* file; + 1300 : block_off_t file_pos; + 1301 : + 1302 51148943 : file = fs_par2file_get_ts(disk, fs_last, parity_pos, &file_pos); + 1303 : + 1304 51044271 : if (!file) + 1305 2337947 : return BLOCK_EMPTY; + 1306 : + 1307 48706324 : return fs_file2block_get(file, file_pos); + 1308 : } + 1309 : + 1310 1447 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid) + 1311 : { + 1312 : struct snapraid_map* map; + 1313 : + 1314 1447 : map = malloc_nofail(sizeof(struct snapraid_map)); + 1315 1447 : pathcpy(map->name, sizeof(map->name), name); + 1316 1447 : map->position = position; + 1317 1447 : map->total_blocks = total_blocks; + 1318 1447 : map->free_blocks = free_blocks; + 1319 1447 : pathcpy(map->uuid, sizeof(map->uuid), uuid); + 1320 : + 1321 1447 : return map; + 1322 : } + 1323 : + 1324 1327 : void map_free(struct snapraid_map* map) + 1325 : { + 1326 1327 : free(map); + 1327 1327 : } + 1328 : + 1329 743492 : int time_compare(const void* void_a, const void* void_b) + 1330 : { + 1331 743492 : const time_t* time_a = void_a; + 1332 743492 : const time_t* time_b = void_b; + 1333 : + 1334 743492 : if (*time_a < *time_b) + 1335 28996 : return -1; + 1336 714496 : if (*time_a > *time_b) + 1337 185655 : return 1; + 1338 528841 : return 0; + 1339 : } diff --git a/cov/cmdline/elem.h.func-sort-c.html b/cov/cmdline/elem.h.func-sort-c.html index cf4a43a7..2a9ac818 100644 --- a/cov/cmdline/elem.h.func-sort-c.html +++ b/cov/cmdline/elem.h.func-sort-c.html @@ -31,17 +31,17 @@ lcov.info Lines: - 118 - 119 - 99.2 % + 115 + 116 + 99.1 % Date: - 2015-11-13 + 2015-11-20 Functions: - 40 - 40 + 39 + 39 100.0 % @@ -59,117 +59,113 @@ Function Name Sort by function name Hit count Sort by hit count - - fs_file2block_get - 114670866 - block_state_get - 96508438 + 96735410 file_flag_has - 33299349 + 33299459 - fs_par2block_get - 21725563 + fs_par2block_get + 21727310 block_state_set - 18241681 + 18242161 block_has_file - 12928240 + 12929086 - fs_par2file_get - 11513278 + fs_par2file_get + 11514087 block_has_invalid_parity - 11488433 + 11489174 - info_get - 10527480 + info_get + 10573034 hash_invalid_set - 8911064 + 8910831 file_stamp_hash - 6139195 + 6139138 file_flag_set - 5178039 + 5176917 file_inode_hash - 4822885 + 4822298 file_path_hash - 3766477 + 3766623 - info_get_rehash - 3293767 + info_get_rehash + 3312725 filter_hidden - 3066757 + 3066852 block_has_past_hash - 2287716 + 2287366 - info_get_time - 2241006 + info_get_time + 2258078 block_has_updated_hash - 2004868 + 2005171 - info_get_bad - 1705083 + info_get_bad + 1725704 - info_set - 1609362 + info_set + 1609485 - info_get_justsynced - 1455572 + info_get_justsynced + 1474627 hash_is_zero - 790624 + 790275 hash_is_invalid - 776390 + 776042 - fs_file2par_get - 602426 + fs_file2par_get + 464306 link_flag_get - 410823 + 410820 - info_make - 390916 + info_make + 394996 block_has_file_and_valid_parity - 221103 + 221100 link_flag_has @@ -185,7 +181,7 @@ hash_is_real - 65665 + 65785 link_flag_set @@ -193,15 +189,15 @@ file_flag_clear - 14861 + 14174 - info_set_rehash + info_set_rehash 9199 - info_set_bad - 1803 + info_set_bad + 1802 dir_name_hash diff --git a/cov/cmdline/elem.h.func.html b/cov/cmdline/elem.h.func.html index 43a320f0..8e76d216 100644 --- a/cov/cmdline/elem.h.func.html +++ b/cov/cmdline/elem.h.func.html @@ -31,17 +31,17 @@ lcov.info Lines: - 118 - 119 - 99.2 % + 115 + 116 + 99.1 % Date: - 2015-11-13 + 2015-11-20 Functions: - 40 - 40 + 39 + 39 100.0 % @@ -61,31 +61,31 @@ block_has_file - 12928240 + 12929086 block_has_file_and_valid_parity - 221103 + 221100 block_has_invalid_parity - 11488433 + 11489174 block_has_past_hash - 2287716 + 2287366 block_has_updated_hash - 2004868 + 2005171 block_state_get - 96508438 + 96735410 block_state_set - 18241681 + 18242161 dir_flag_has @@ -101,107 +101,103 @@ file_flag_clear - 14861 + 14174 file_flag_has - 33299349 + 33299459 file_flag_set - 5178039 + 5176917 file_inode_hash - 4822885 + 4822298 file_path_hash - 3766477 + 3766623 file_stamp_hash - 6139195 + 6139138 filter_hidden - 3066757 + 3066852 - fs_file2block_get - 114670866 + fs_file2par_get + 464306 - fs_file2par_get - 602426 + fs_par2block_get + 21727310 - fs_par2block_get - 21725563 - - - fs_par2file_get - 11513278 + fs_par2file_get + 11514087 hash_invalid_set - 8911064 + 8910831 hash_is_invalid - 776390 + 776042 hash_is_real - 65665 + 65785 hash_is_zero - 790624 + 790275 hash_zero_set 153288 - info_get - 10527480 + info_get + 10573034 - info_get_bad - 1705083 + info_get_bad + 1725704 - info_get_justsynced - 1455572 + info_get_justsynced + 1474627 - info_get_rehash - 3293767 + info_get_rehash + 3312725 - info_get_time - 2241006 + info_get_time + 2258078 - info_make - 390916 + info_make + 394996 - info_set - 1609362 + info_set + 1609485 - info_set_bad - 1803 + info_set_bad + 1802 - info_set_rehash + info_set_rehash 9199 link_flag_get - 410823 + 410820 link_flag_has diff --git a/cov/cmdline/elem.h.gcov.html b/cov/cmdline/elem.h.gcov.html index e75a6eee..c8f25c02 100644 --- a/cov/cmdline/elem.h.gcov.html +++ b/cov/cmdline/elem.h.gcov.html @@ -31,17 +31,17 @@ lcov.info Lines: - 118 - 119 - 99.2 % + 115 + 116 + 99.1 % Date: - 2015-11-13 + 2015-11-20 Functions: - 40 - 40 + 39 + 39 100.0 % @@ -517,13 +517,13 @@ 455 : * Filter hidden files. 456 : * Return !=0 if it matches and it should be excluded. 457 : */ - 458 3066757 : static inline int filter_hidden(int enable, struct dirent* dd) + 458 3066852 : static inline int filter_hidden(int enable, struct dirent* dd) 459 : { - 460 3066757 : if (enable && dirent_hidden(dd)) { + 460 3066852 : if (enable && dirent_hidden(dd)) { 461 0 : return 1; /* filter out */ 462 : } 463 : - 464 3066757 : return 0; + 464 3066852 : return 0; 465 : } 466 : 467 : /** @@ -564,13 +564,13 @@ 502 : * 503 : * An invalid hash is represented with all bytes at 0x00. 504 : */ - 505 776390 : static inline int hash_is_invalid(const unsigned char* hash) + 505 776042 : static inline int hash_is_invalid(const unsigned char* hash) 506 : { 507 : unsigned i; 508 : - 509 1265344 : for (i = 0; i < HASH_SIZE; ++i) - 510 1234968 : if (hash[i] != 0x00) - 511 746014 : return 0; + 509 1264688 : for (i = 0; i < HASH_SIZE; ++i) + 510 1234312 : if (hash[i] != 0x00) + 511 745666 : return 0; 512 : 513 30376 : return 1; 514 : } @@ -580,13 +580,13 @@ 518 : * 519 : * A zero hash is represented with all bytes at 0xFF. 520 : */ - 521 790624 : static inline int hash_is_zero(const unsigned char* hash) + 521 790275 : static inline int hash_is_zero(const unsigned char* hash) 522 : { 523 : unsigned i; 524 : - 525 1835995 : for (i = 0; i < HASH_SIZE; ++i) - 526 1770815 : if (hash[i] != 0xFF) - 527 725444 : return 0; + 525 1835799 : for (i = 0; i < HASH_SIZE; ++i) + 526 1770619 : if (hash[i] != 0xFF) + 527 725095 : return 0; 528 : 529 65180 : return 1; 530 : } @@ -594,18 +594,18 @@ 532 : /** 533 : * Check if the specified hash is a real hash. 534 : */ - 535 65665 : static inline int hash_is_real(const unsigned char* hash) + 535 65785 : static inline int hash_is_real(const unsigned char* hash) 536 : { - 537 65665 : return !hash_is_zero(hash) && !hash_is_invalid(hash); + 537 65785 : return !hash_is_zero(hash) && !hash_is_invalid(hash); 538 : } 539 : 540 : /** 541 : * Set the hash to the special INVALID value. 542 : */ - 543 8911064 : static inline void hash_invalid_set(unsigned char* hash) + 543 8910831 : static inline void hash_invalid_set(unsigned char* hash) 544 : { - 545 8911064 : memset(hash, 0x00, HASH_SIZE); - 546 8911064 : } + 545 8910831 : memset(hash, 0x00, HASH_SIZE); + 546 8910831 : } 547 : 548 : /** 549 : * Set the hash to the special ZERO value. @@ -621,32 +621,32 @@ 559 : * For this function, it's allowed to pass a NULL block 560 : * pointer than results in the BLOCK_STATE_EMPTY state. 561 : */ - 562 96508438 : static inline unsigned block_state_get(const struct snapraid_block* block) + 562 96735410 : static inline unsigned block_state_get(const struct snapraid_block* block) 563 : { - 564 96508438 : if (block == BLOCK_EMPTY) - 565 2429041 : return BLOCK_STATE_EMPTY; + 564 96735410 : if (block == BLOCK_EMPTY) + 565 2427201 : return BLOCK_STATE_EMPTY; 566 : - 567 94079397 : return block->state; + 567 94308209 : return block->state; 568 : } 569 : 570 : /** 571 : * Set the state of the block. 572 : */ - 573 18241681 : static inline void block_state_set(struct snapraid_block* block, unsigned state) + 573 18242161 : static inline void block_state_set(struct snapraid_block* block, unsigned state) 574 : { - 575 18241681 : block->state = state; - 576 18241681 : } + 575 18242161 : block->state = state; + 576 18242161 : } 577 : 578 : /** 579 : * Check if the specified block has an updated hash. 580 : * 581 : * Note that EMPTY / CHG / DELETED return 0. 582 : */ - 583 2004868 : static inline int block_has_updated_hash(const struct snapraid_block* block) + 583 2005171 : static inline int block_has_updated_hash(const struct snapraid_block* block) 584 : { - 585 2004868 : unsigned state = block_state_get(block); + 585 2005171 : unsigned state = block_state_get(block); 586 : - 587 2004868 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP; + 587 2005171 : return state == BLOCK_STATE_BLK || state == BLOCK_STATE_REP; 588 : } 589 : 590 : /** @@ -655,11 +655,11 @@ 593 : * 594 : * Note that EMPTY / BLK / REP return 0. 595 : */ - 596 2287716 : static inline int block_has_past_hash(const struct snapraid_block* block) + 596 2287366 : static inline int block_has_past_hash(const struct snapraid_block* block) 597 : { - 598 2287716 : unsigned state = block_state_get(block); + 598 2287366 : unsigned state = block_state_get(block); 599 : - 600 2287716 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED; + 600 2287366 : return state == BLOCK_STATE_CHG || state == BLOCK_STATE_DELETED; 601 : } 602 : 603 : /** @@ -667,12 +667,12 @@ 605 : * 606 : * Note that EMPTY / DELETED return 0. 607 : */ - 608 12928240 : static inline int block_has_file(const struct snapraid_block* block) + 608 12929086 : static inline int block_has_file(const struct snapraid_block* block) 609 : { - 610 12928240 : unsigned state = block_state_get(block); + 610 12929086 : unsigned state = block_state_get(block); 611 : - 612 12928240 : return state == BLOCK_STATE_BLK - 613 12928240 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; + 612 12929086 : return state == BLOCK_STATE_BLK + 613 12929086 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; 614 : } 615 : 616 : /** @@ -680,12 +680,12 @@ 618 : * 619 : * Note that EMPTY / BLK return 0. 620 : */ - 621 11488433 : static inline int block_has_invalid_parity(const struct snapraid_block* block) + 621 11489174 : static inline int block_has_invalid_parity(const struct snapraid_block* block) 622 : { - 623 11488433 : unsigned state = block_state_get(block); + 623 11489174 : unsigned state = block_state_get(block); 624 : - 625 11488433 : return state == BLOCK_STATE_DELETED - 626 11488433 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; + 625 11489174 : return state == BLOCK_STATE_DELETED + 626 11489174 : || state == BLOCK_STATE_CHG || state == BLOCK_STATE_REP; 627 : } 628 : 629 : /** @@ -693,27 +693,27 @@ 631 : * 632 : * Note that anything different than BLK return 0. 633 : */ - 634 221103 : static inline int block_has_file_and_valid_parity(const struct snapraid_block* block) + 634 221100 : static inline int block_has_file_and_valid_parity(const struct snapraid_block* block) 635 : { - 636 221103 : unsigned state = block_state_get(block); + 636 221100 : unsigned state = block_state_get(block); 637 : - 638 221103 : return state == BLOCK_STATE_BLK; + 638 221100 : return state == BLOCK_STATE_BLK; 639 : } 640 : - 641 33299349 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask) + 641 33299459 : static inline int file_flag_has(const struct snapraid_file* file, unsigned mask) 642 : { - 643 33299349 : return (file->flag & mask) == mask; + 643 33299459 : return (file->flag & mask) == mask; 644 : } 645 : - 646 5178039 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask) + 646 5176917 : static inline void file_flag_set(struct snapraid_file* file, unsigned mask) 647 : { - 648 5178039 : file->flag |= mask; - 649 5178039 : } + 648 5176917 : file->flag |= mask; + 649 5176917 : } 650 : - 651 14861 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask) + 651 14174 : static inline void file_flag_clear(struct snapraid_file* file, unsigned mask) 652 : { - 653 14861 : file->flag &= ~mask; - 654 14861 : } + 653 14174 : file->flag &= ~mask; + 654 14174 : } 655 : 656 : /** 657 : * Allocate a file. @@ -779,9 +779,9 @@ 717 : /** 718 : * Compute the hash of a file inode. 719 : */ - 720 4822885 : static inline tommy_uint32_t file_inode_hash(uint64_t inode) + 720 4822298 : static inline tommy_uint32_t file_inode_hash(uint64_t inode) 721 : { - 722 4822885 : return (tommy_uint32_t)tommy_inthash_u64(inode); + 722 4822298 : return (tommy_uint32_t)tommy_inthash_u64(inode); 723 : } 724 : 725 : /** @@ -800,17 +800,17 @@ 738 : /** 739 : * Compute the hash of a file path. 740 : */ - 741 3766477 : static inline tommy_uint32_t file_path_hash(const char* sub) + 741 3766623 : static inline tommy_uint32_t file_path_hash(const char* sub) 742 : { - 743 3766477 : return tommy_hash_u32(0, sub, strlen(sub)); + 743 3766623 : return tommy_hash_u32(0, sub, strlen(sub)); 744 : } 745 : 746 : /** 747 : * Compute the hash of a file stamp. 748 : */ - 749 6139195 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec) + 749 6139138 : static inline tommy_uint32_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec) 750 : { - 751 6139195 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec))); + 751 6139138 : return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32(mtime_sec ^ tommy_inthash_u32(mtime_nsec))); 752 : } 753 : 754 : /** @@ -854,9 +854,9 @@ 792 6 : slink->flag |= flag & mask; 793 6 : } 794 : - 795 410823 : static inline unsigned link_flag_get(struct snapraid_link* slink, unsigned mask) + 795 410820 : static inline unsigned link_flag_get(struct snapraid_link* slink, unsigned mask) 796 : { - 797 410823 : return slink->flag & mask; + 797 410820 : return slink->flag & mask; 798 : } 799 : 800 : /** @@ -975,181 +975,176 @@ 913 : void fs_deallocate(struct snapraid_disk* disk, block_off_t pos); 914 : 915 : /** - 916 : * Get the block from the file position. + 916 : * Get the block from the file position. 917 : */ - 918 114670866 : static inline struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos) - 919 : { - 920 114670866 : assert(file_pos < file->blockmax); - 921 : - 922 114670866 : return &file->blockvec[file_pos]; - 923 : } + 918 : struct snapraid_block* fs_file2block_get(struct snapraid_file* file, block_off_t file_pos); + 919 : + 920 : /** + 921 : * Like fs_file2par_get() but thread-safe. + 922 : */ + 923 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos); 924 : 925 : /** - 926 : * Like fs_file2par_get() but thread-safe. - 927 : */ - 928 : struct snapraid_file* fs_par2file_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos, block_off_t* file_pos); - 929 : - 930 : /** - 931 : * Get the file position from the parity position. - 932 : * Return 0 if no file is using it. - 933 : * \note This function is NOT thread-safe as it uses the the disk cache. - 934 : */ - 935 11513278 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos) - 936 : { - 937 11513278 : return fs_par2file_get_ts(disk, &disk->fs_last, parity_pos, file_pos); - 938 : } + 926 : * Get the file position from the parity position. + 927 : * Return 0 if no file is using it. + 928 : * \note This function is NOT thread-safe as it uses the the disk cache. + 929 : */ + 930 11514087 : static inline struct snapraid_file* fs_par2file_get(struct snapraid_disk* disk, block_off_t parity_pos, block_off_t* file_pos) + 931 : { + 932 11514087 : return fs_par2file_get_ts(disk, &disk->fs_last, parity_pos, file_pos); + 933 : } + 934 : + 935 : /** + 936 : * Like fs_file2par_get() but thread-safe. + 937 : */ + 938 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos); 939 : 940 : /** - 941 : * Like fs_file2par_get() but thread-safe. - 942 : */ - 943 : block_off_t fs_file2par_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, struct snapraid_file* file, block_off_t file_pos); - 944 : - 945 : /** - 946 : * Get the parity position from the file position. - 947 : * \note This function is NOT thread-safe as it uses the the disk cache. - 948 : */ - 949 602426 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos) - 950 : { - 951 602426 : return fs_file2par_get_ts(disk, &disk->fs_last, file, file_pos); - 952 : } + 941 : * Get the parity position from the file position. + 942 : * \note This function is NOT thread-safe as it uses the the disk cache. + 943 : */ + 944 464306 : static inline block_off_t fs_file2par_get(struct snapraid_disk* disk, struct snapraid_file* file, block_off_t file_pos) + 945 : { + 946 464306 : return fs_file2par_get_ts(disk, &disk->fs_last, file, file_pos); + 947 : } + 948 : + 949 : /** + 950 : * Like fs_par2block_get() but thread-safe. + 951 : */ + 952 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos); 953 : 954 : /** - 955 : * Like fs_par2block_get() but thread-safe. - 956 : */ - 957 : struct snapraid_block* fs_par2block_get_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t parity_pos); - 958 : - 959 : /** - 960 : * Get the block from the parity position. - 961 : * Return BLOCK_EMPTY==0 if the block is over the end of the disk or not used. - 962 : * \note This function is NOT thread-safe as it uses the the disk cache. - 963 : */ - 964 21725563 : static inline struct snapraid_block* fs_par2block_get(struct snapraid_disk* disk, block_off_t parity_pos) - 965 : { - 966 21725563 : return fs_par2block_get_ts(disk, &disk->fs_last, parity_pos); - 967 : } - 968 : - 969 : /** - 970 : * Allocate a disk mapping. - 971 : * Uses uuid="" if not available. + 955 : * Get the block from the parity position. + 956 : * Return BLOCK_EMPTY==0 if the block is over the end of the disk or not used. + 957 : * \note This function is NOT thread-safe as it uses the the disk cache. + 958 : */ + 959 21727310 : static inline struct snapraid_block* fs_par2block_get(struct snapraid_disk* disk, block_off_t parity_pos) + 960 : { + 961 21727310 : return fs_par2block_get_ts(disk, &disk->fs_last, parity_pos); + 962 : } + 963 : + 964 : /** + 965 : * Allocate a disk mapping. + 966 : * Uses uuid="" if not available. + 967 : */ + 968 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid); + 969 : + 970 : /** + 971 : * Deallocate a disk mapping. 972 : */ - 973 : struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid); + 973 : void map_free(struct snapraid_map* map); 974 : 975 : /** - 976 : * Deallocate a disk mapping. - 977 : */ - 978 : void map_free(struct snapraid_map* map); - 979 : - 980 : /** - 981 : * Mask used to store additional information in the info bits. - 982 : * - 983 : * These bits reduce the granurality of the time in the memory representation. + 976 : * Mask used to store additional information in the info bits. + 977 : * + 978 : * These bits reduce the granurality of the time in the memory representation. + 979 : */ + 980 : #define INFO_MASK 0x7 + 981 : + 982 : /** + 983 : * Make an info. 984 : */ - 985 : #define INFO_MASK 0x7 - 986 : - 987 : /** - 988 : * Make an info. - 989 : */ - 990 390916 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced) - 991 : { - 992 : /* clear the lowest bits as reserved for other information */ - 993 390916 : snapraid_info info = last_access & ~INFO_MASK; - 994 : - 995 390916 : if (error != 0) - 996 5433 : info |= 0x1; - 997 390916 : if (rehash != 0) - 998 127410 : info |= 0x2; - 999 390916 : if (justsynced != 0) - 1000 226165 : info |= 0x4; - 1001 390916 : return info; - 1002 : } - 1003 : - 1004 : /** - 1005 : * Extract the time information. - 1006 : * This is the last time when the block was know to be correct. - 1007 : * The "scrubbed" info tells if the time is referreing at the latest sync or scrub. - 1008 : */ - 1009 2241006 : static inline time_t info_get_time(snapraid_info info) - 1010 : { - 1011 2241006 : return info & ~INFO_MASK; - 1012 : } - 1013 : - 1014 : /** - 1015 : * Extract the error information. - 1016 : * Report if the block address had some problem. - 1017 : */ - 1018 1705083 : static inline int info_get_bad(snapraid_info info) - 1019 : { - 1020 1705083 : return (info & 0x1) != 0; - 1021 : } - 1022 : - 1023 : /** - 1024 : * Extract the rehash information. - 1025 : * Report if the block address is using the old hash and needs to be rehashed. - 1026 : */ - 1027 3293767 : static inline int info_get_rehash(snapraid_info info) - 1028 : { - 1029 3293767 : return (info & 0x2) != 0; - 1030 : } - 1031 : - 1032 : /** - 1033 : * Extract the scrubbed information. - 1034 : * Report if the block address was never scrubbed. - 1035 : */ - 1036 1455572 : static inline int info_get_justsynced(snapraid_info info) - 1037 : { - 1038 1455572 : return (info & 0x4) != 0; - 1039 : } - 1040 : - 1041 : /** - 1042 : * Mark the block address as with error. - 1043 : */ - 1044 1803 : static inline snapraid_info info_set_bad(snapraid_info info) - 1045 : { - 1046 1803 : return info | 0x1; - 1047 : } - 1048 : - 1049 : /** - 1050 : * Mark the block address as with rehash. - 1051 : */ - 1052 9199 : static inline snapraid_info info_set_rehash(snapraid_info info) - 1053 : { - 1054 9199 : return info | 0x2; - 1055 : } - 1056 : - 1057 : /** - 1058 : * Set the info at the specified position. - 1059 : * The position is allocated if not yet done. - 1060 : */ - 1061 1609362 : static inline void info_set(tommy_arrayblkof* array, unsigned pos, snapraid_info info) - 1062 : { - 1063 1609362 : tommy_arrayblkof_grow(array, pos + 1); - 1064 : - 1065 1609362 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info)); - 1066 1609362 : } - 1067 : - 1068 : /** - 1069 : * Get the info at the specified position. - 1070 : * For not allocated position, 0 is returned. - 1071 : */ - 1072 10527480 : static inline snapraid_info info_get(tommy_arrayblkof* array, unsigned pos) - 1073 : { - 1074 : snapraid_info info; + 985 394996 : static inline snapraid_info info_make(time_t last_access, int error, int rehash, int justsynced) + 986 : { + 987 : /* clear the lowest bits as reserved for other information */ + 988 394996 : snapraid_info info = last_access & ~INFO_MASK; + 989 : + 990 394996 : if (error != 0) + 991 5460 : info |= 0x1; + 992 394996 : if (rehash != 0) + 993 127410 : info |= 0x2; + 994 394996 : if (justsynced != 0) + 995 226412 : info |= 0x4; + 996 394996 : return info; + 997 : } + 998 : + 999 : /** + 1000 : * Extract the time information. + 1001 : * This is the last time when the block was know to be correct. + 1002 : * The "scrubbed" info tells if the time is referreing at the latest sync or scrub. + 1003 : */ + 1004 2258078 : static inline time_t info_get_time(snapraid_info info) + 1005 : { + 1006 2258078 : return info & ~INFO_MASK; + 1007 : } + 1008 : + 1009 : /** + 1010 : * Extract the error information. + 1011 : * Report if the block address had some problem. + 1012 : */ + 1013 1725704 : static inline int info_get_bad(snapraid_info info) + 1014 : { + 1015 1725704 : return (info & 0x1) != 0; + 1016 : } + 1017 : + 1018 : /** + 1019 : * Extract the rehash information. + 1020 : * Report if the block address is using the old hash and needs to be rehashed. + 1021 : */ + 1022 3312725 : static inline int info_get_rehash(snapraid_info info) + 1023 : { + 1024 3312725 : return (info & 0x2) != 0; + 1025 : } + 1026 : + 1027 : /** + 1028 : * Extract the scrubbed information. + 1029 : * Report if the block address was never scrubbed. + 1030 : */ + 1031 1474627 : static inline int info_get_justsynced(snapraid_info info) + 1032 : { + 1033 1474627 : return (info & 0x4) != 0; + 1034 : } + 1035 : + 1036 : /** + 1037 : * Mark the block address as with error. + 1038 : */ + 1039 1802 : static inline snapraid_info info_set_bad(snapraid_info info) + 1040 : { + 1041 1802 : return info | 0x1; + 1042 : } + 1043 : + 1044 : /** + 1045 : * Mark the block address as with rehash. + 1046 : */ + 1047 9199 : static inline snapraid_info info_set_rehash(snapraid_info info) + 1048 : { + 1049 9199 : return info | 0x2; + 1050 : } + 1051 : + 1052 : /** + 1053 : * Set the info at the specified position. + 1054 : * The position is allocated if not yet done. + 1055 : */ + 1056 1609485 : static inline void info_set(tommy_arrayblkof* array, unsigned pos, snapraid_info info) + 1057 : { + 1058 1609485 : tommy_arrayblkof_grow(array, pos + 1); + 1059 : + 1060 1609485 : memcpy(tommy_arrayblkof_ref(array, pos), &info, sizeof(snapraid_info)); + 1061 1609485 : } + 1062 : + 1063 : /** + 1064 : * Get the info at the specified position. + 1065 : * For not allocated position, 0 is returned. + 1066 : */ + 1067 10573034 : static inline snapraid_info info_get(tommy_arrayblkof* array, unsigned pos) + 1068 : { + 1069 : snapraid_info info; + 1070 : + 1071 10573034 : if (pos >= tommy_arrayblkof_size(array)) + 1072 474047 : return 0; + 1073 : + 1074 10073489 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info)); 1075 : - 1076 10527480 : if (pos >= tommy_arrayblkof_size(array)) - 1077 477684 : return 0; + 1076 10085303 : return info; + 1077 : } 1078 : - 1079 10051219 : memcpy(&info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info)); - 1080 : - 1081 10056067 : return info; - 1082 : } + 1079 : /** + 1080 : * Compare times + 1081 : */ + 1082 : int time_compare(const void* void_a, const void* void_b); 1083 : - 1084 : /** - 1085 : * Compare times - 1086 : */ - 1087 : int time_compare(const void* void_a, const void* void_b); - 1088 : - 1089 : #endif - 1090 : + 1084 : #endif + 1085 : diff --git a/cov/cmdline/handle.c.func-sort-c.html b/cov/cmdline/handle.c.func-sort-c.html index 786e0389..364aeee3 100644 --- a/cov/cmdline/handle.c.func-sort-c.html +++ b/cov/cmdline/handle.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 @@ -61,31 +61,31 @@ handle_read - 5655264 + 5656394 handle_close - 4567924 + 4568631 handle_open - 1971646 + 1972488 handle_create - 771245 + 771210 handle_write - 288250 + 288205 handle_utime - 117835 + 117763 handle_truncate - 3177 + 3249 handle_map diff --git a/cov/cmdline/handle.c.func.html b/cov/cmdline/handle.c.func.html index 80c45654..f0a579bc 100644 --- a/cov/cmdline/handle.c.func.html +++ b/cov/cmdline/handle.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 @@ -61,11 +61,11 @@ handle_close - 4567924 + 4568631 handle_create - 771245 + 771210 handle_map @@ -73,23 +73,23 @@ handle_open - 1971646 + 1972488 handle_read - 5655264 + 5656394 handle_truncate - 3177 + 3249 handle_utime - 117835 + 117763 handle_write - 288250 + 288205
diff --git a/cov/cmdline/handle.c.gcov.html b/cov/cmdline/handle.c.gcov.html index 33da53e7..72e13a47 100644 --- a/cov/cmdline/handle.c.gcov.html +++ b/cov/cmdline/handle.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 @@ -86,66 +86,66 @@ 24 : /****************************************************************************/ 25 : /* handle */ 26 : - 27 771245 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode) + 27 771210 : int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode) 28 : { 29 : int ret; 30 : int flags; 31 : 32 : /* if it's the same file, and already opened, nothing to do */ - 33 771245 : if (handle->file == file && handle->f != -1) { + 33 771210 : if (handle->file == file && handle->f != -1) { 34 0 : return 0; 35 : } 36 : - 37 771245 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); + 37 771210 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); 38 : - 39 771245 : ret = mkancestor(handle->path); - 40 771245 : if (ret != 0) { + 39 771210 : ret = mkancestor(handle->path); + 40 771210 : if (ret != 0) { 41 : /* LCOV_EXCL_START */ 42 : return -1; 43 : /* LCOV_EXCL_STOP */ 44 : } 45 : 46 : /* initial values, changed later if required */ - 47 771245 : handle->created = 0; + 47 771210 : handle->created = 0; 48 : 49 : /* flags for opening */ 50 : /* O_BINARY: open as binary file (Windows only) */ 51 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ 52 : /* O_SEQUENTIAL: improve performance for sequential access (Windows only) */ - 53 771245 : flags = O_BINARY | O_NOFOLLOW; - 54 771245 : if ((mode & MODE_SEQUENTIAL) != 0) - 55 771245 : flags |= O_SEQUENTIAL; + 53 771210 : flags = O_BINARY | O_NOFOLLOW; + 54 771210 : if ((mode & MODE_SEQUENTIAL) != 0) + 55 771210 : flags |= O_SEQUENTIAL; 56 : 57 : /* open for read write */ - 58 771245 : handle->f = open(handle->path, flags | O_RDWR); + 58 771210 : handle->f = open(handle->path, flags | O_RDWR); 59 : 60 : /* if failed for missing write permission */ - 61 771245 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) { + 61 771210 : if (handle->f == -1 && (errno == EACCES || errno == EROFS)) { 62 : /* open for real-only */ 63 0 : handle->f = open(handle->path, flags | O_RDONLY); 64 : } 65 : 66 : /* if failed for missing file */ - 67 771245 : if (handle->f == -1 && errno == ENOENT) { + 67 771210 : if (handle->f == -1 && errno == ENOENT) { 68 : char path_from[PATH_MAX]; 69 : 70 : /* check if exists a .unrecoverable copy, and rename to the real one */ - 71 176510 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path); + 71 176420 : pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path); 72 : - 73 176510 : if (rename(path_from, handle->path) == 0) { + 73 176420 : if (rename(path_from, handle->path) == 0) { 74 : /* open for read write */ - 75 63467 : handle->f = open(handle->path, flags | O_RDWR); + 75 63396 : handle->f = open(handle->path, flags | O_RDWR); 76 : } else { 77 : /* create it */ - 78 113043 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600); - 79 113043 : if (handle->f != -1) { + 78 113024 : handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600); + 79 113024 : if (handle->f != -1) { 80 : /* mark it as created if really done */ - 81 113043 : handle->created = 1; + 81 113024 : handle->created = 1; 82 : } 83 : } 84 : } 85 : - 86 771245 : if (handle->f == -1) { + 86 771210 : if (handle->f == -1) { 87 : /* LCOV_EXCL_START */ 88 : /* invalidate for error */ 89 : handle->file = 0; @@ -158,11 +158,11 @@ 96 : } 97 : 98 : /* just opened */ - 99 771245 : handle->file = file; + 99 771210 : handle->file = file; 100 : 101 : /* get the stat info */ - 102 771245 : ret = fstat(handle->f, &handle->st); - 103 771245 : if (ret != 0) { + 102 771210 : ret = fstat(handle->f, &handle->st); + 103 771210 : if (ret != 0) { 104 : /* LCOV_EXCL_START */ 105 : log_fatal("Error accessing file '%s'. %s.\n", handle->path, strerror(errno)); 106 : return -1; @@ -170,13 +170,13 @@ 108 : } 109 : 110 : /* get the size of the existing data */ - 111 771245 : handle->valid_size = handle->st.st_size; + 111 771210 : handle->valid_size = handle->st.st_size; 112 : 113 : #if HAVE_POSIX_FADVISE - 114 771245 : if ((mode & MODE_SEQUENTIAL) != 0) { + 114 771210 : if ((mode & MODE_SEQUENTIAL) != 0) { 115 : /* advise sequential access */ - 116 771245 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL); - 117 771245 : if (ret != 0) { + 116 771210 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL); + 117 771210 : if (ret != 0) { 118 : /* LCOV_EXCL_START */ 119 : log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(ret)); 120 : return -1; @@ -185,15 +185,15 @@ 123 : } 124 : #endif 125 : - 126 771245 : return 0; + 126 771210 : return 0; 127 : } 128 : - 129 3177 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file) + 129 3249 : int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file) 130 : { 131 : int ret; 132 : - 133 3177 : ret = ftruncate(handle->f, file->size); - 134 3177 : if (ret != 0) { + 133 3249 : ret = ftruncate(handle->f, file->size); + 134 3249 : if (ret != 0) { 135 : /* LCOV_EXCL_START */ 136 : if (errno == EACCES) { 137 : log_fatal("Failed to truncate file '%s' for missing write permission.\n", handle->path); @@ -205,58 +205,58 @@ 143 : } 144 : 145 : /* adjust the size to the truncated size */ - 146 3177 : handle->valid_size = file->size; + 146 3249 : handle->valid_size = file->size; 147 : - 148 3177 : return 0; + 148 3249 : return 0; 149 : } 150 : - 151 1971646 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing) + 151 1972488 : int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing) 152 : { 153 : int ret; 154 : int flags; 155 : - 156 1971646 : if (!out_missing) - 157 1971130 : out_missing = out; + 156 1972488 : if (!out_missing) + 157 1971972 : out_missing = out; 158 : 159 : /* if already opened, nothing to do */ - 160 1971646 : if (handle->file == file && handle->f != -1) { - 161 332255 : return 0; + 160 1972488 : if (handle->file == file && handle->f != -1) { + 161 332290 : return 0; 162 : } 163 : - 164 1639391 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); + 164 1640198 : pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); 165 : 166 : /* for sure not created */ - 167 1639391 : handle->created = 0; + 167 1640198 : handle->created = 0; 168 : 169 : /* flags for opening */ 170 : /* O_BINARY: open as binary file (Windows only) */ 171 : /* O_NOFOLLOW: do not follow links to ensure to open the real file */ 172 : /* O_SEQUENTIAL: improve performance for sequential access (Windows only) */ - 173 1639391 : flags = O_BINARY | O_NOFOLLOW; - 174 1639391 : if ((mode & MODE_SEQUENTIAL) != 0) - 175 1628063 : flags |= O_SEQUENTIAL; + 173 1640198 : flags = O_BINARY | O_NOFOLLOW; + 174 1640198 : if ((mode & MODE_SEQUENTIAL) != 0) + 175 1628870 : flags |= O_SEQUENTIAL; 176 : 177 : /* open for read */ - 178 1639391 : handle->f = open_noatime(handle->path, flags | O_RDONLY); - 179 1639391 : if (handle->f == -1) { + 178 1640198 : handle->f = open_noatime(handle->path, flags | O_RDONLY); + 179 1640198 : if (handle->f == -1) { 180 : /* invalidate for error */ - 181 78905 : handle->file = 0; - 182 78905 : handle->f = -1; - 183 78905 : handle->valid_size = 0; + 181 78777 : handle->file = 0; + 182 78777 : handle->f = -1; + 183 78777 : handle->valid_size = 0; 184 : - 185 78905 : if (errno == ENOENT) - 186 78893 : out_missing("Missing file '%s'.\n", handle->path); + 185 78777 : if (errno == ENOENT) + 186 78765 : out_missing("Missing file '%s'.\n", handle->path); 187 : else 188 12 : out("Error opening file '%s'. %s.\n", handle->path, strerror(errno)); - 189 78905 : return -1; + 189 78777 : return -1; 190 : } 191 : 192 : /* just opened */ - 193 1560486 : handle->file = file; + 193 1561421 : handle->file = file; 194 : 195 : /* get the stat info */ - 196 1560486 : ret = fstat(handle->f, &handle->st); - 197 1560486 : if (ret != 0) { + 196 1561421 : ret = fstat(handle->f, &handle->st); + 197 1561421 : if (ret != 0) { 198 : /* LCOV_EXCL_START */ 199 : out("Error accessing file '%s'. %s.\n", handle->path, strerror(errno)); 200 : return -1; @@ -264,13 +264,13 @@ 202 : } 203 : 204 : /* get the size of the existing data */ - 205 1560486 : handle->valid_size = handle->st.st_size; + 205 1561421 : handle->valid_size = handle->st.st_size; 206 : 207 : #if HAVE_POSIX_FADVISE - 208 1560486 : if ((mode & MODE_SEQUENTIAL) != 0) { + 208 1561421 : if ((mode & MODE_SEQUENTIAL) != 0) { 209 : /* advise sequential access */ - 210 1549158 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL); - 211 1549158 : if (ret != 0) { + 210 1550093 : ret = posix_fadvise(handle->f, 0, 0, POSIX_FADV_SEQUENTIAL); + 211 1550093 : if (ret != 0) { 212 : /* LCOV_EXCL_START */ 213 : out("Error advising file '%s'. %s.\n", handle->path, strerror(ret)); 214 : return -1; @@ -279,17 +279,17 @@ 217 : } 218 : #endif 219 : - 220 1560486 : return 0; + 220 1561421 : return 0; 221 : } 222 : - 223 4567924 : int handle_close(struct snapraid_handle* handle) + 223 4568631 : int handle_close(struct snapraid_handle* handle) 224 : { 225 : int ret; 226 : 227 : /* close if open */ - 228 4567924 : if (handle->f != -1) { - 229 2331731 : ret = close(handle->f); - 230 2331731 : if (ret != 0) { + 228 4568631 : if (handle->f != -1) { + 229 2332631 : ret = close(handle->f); + 230 2332631 : if (ret != 0) { 231 : /* LCOV_EXCL_START */ 232 : log_fatal("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno)); 233 : @@ -303,36 +303,36 @@ 241 : } 242 : 243 : /* reset the descriptor */ - 244 4567924 : handle->file = 0; - 245 4567924 : handle->f = -1; - 246 4567924 : handle->valid_size = 0; + 244 4568631 : handle->file = 0; + 245 4568631 : handle->f = -1; + 246 4568631 : handle->valid_size = 0; 247 : - 248 4567924 : return 0; + 248 4568631 : return 0; 249 : } 250 : - 251 5655264 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing) + 251 5656394 : int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing) 252 : { 253 : ssize_t read_ret; 254 : data_off_t offset; 255 : unsigned read_size; 256 : unsigned count; 257 : - 258 5655264 : offset = file_pos * (data_off_t)block_size; + 258 5656394 : offset = file_pos * (data_off_t)block_size; 259 : - 260 5655264 : if (!out_missing) - 261 5641863 : out_missing = out; + 260 5656394 : if (!out_missing) + 261 5642993 : out_missing = out; 262 : 263 : /* check if we are going to read only not initialized data */ - 264 5655264 : if (offset >= handle->valid_size) { + 264 5656394 : if (offset >= handle->valid_size) { 265 : /* if the file is missing, it's at 0 size, or it's rebuilt while reading */ - 266 433381 : if (offset == handle->valid_size || handle->valid_size == 0) - 267 431954 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset); + 266 433131 : if (offset == handle->valid_size || handle->valid_size == 0) + 267 431906 : out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset); 268 : else - 269 1427 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset); - 270 433381 : return -1; + 269 1225 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset); + 270 433131 : return -1; 271 : } 272 : - 273 5221883 : read_size = file_block_size(handle->file, file_pos, block_size); + 273 5223263 : read_size = file_block_size(handle->file, file_pos, block_size); 274 : 275 : #if !HAVE_PREAD 276 : if (lseek(handle->f, offset, SEEK_SET) != offset) { @@ -343,32 +343,32 @@ 281 : } 282 : #endif 283 : - 284 5221883 : count = 0; + 284 5223263 : count = 0; 285 : do { 286 : 287 : #if HAVE_PREAD - 288 5230877 : read_ret = pread(handle->f, block_buffer + count, read_size - count, offset + count); + 288 5232157 : read_ret = pread(handle->f, block_buffer + count, read_size - count, offset + count); 289 : #else 290 : read_ret = read(handle->f, block_buffer + count, read_size - count); 291 : #endif 292 : - 293 5230877 : if (read_ret < 0) { + 293 5232157 : if (read_ret < 0) { 294 : /* LCOV_EXCL_START */ 295 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, read_size - count, strerror(errno)); 296 : return -1; 297 : /* LCOV_EXCL_STOP */ 298 : } - 299 5230877 : if (read_ret == 0) { - 300 8994 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno)); - 301 8994 : return -1; + 299 5232157 : if (read_ret == 0) { + 300 8894 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno)); + 301 8894 : return -1; 302 : } 303 : - 304 5221883 : count += read_ret; - 305 5221883 : } while (count < read_size); + 304 5223263 : count += read_ret; + 305 5223263 : } while (count < read_size); 306 : 307 : /* pad with 0 */ - 308 5212889 : if (read_size < block_size) { - 309 2111431 : memset(block_buffer + read_size, 0, block_size - read_size); + 308 5214369 : if (read_size < block_size) { + 309 2112031 : memset(block_buffer + read_size, 0, block_size - read_size); 310 : } 311 : 312 : /* Here isn't needed to call posix_fadvise(..., POSIX_FADV_DONTNEED) */ @@ -382,21 +382,21 @@ 320 : /* at: https://lkml.org/lkml/2010/12/6/122 */ 321 : /* We relay only on the automatic readahead triggered by POSIX_FADV_SEQUENTIAL. */ 322 : - 323 5212889 : return read_size; + 323 5214369 : return read_size; 324 : } 325 : - 326 288250 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size) + 326 288205 : int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size) 327 : { 328 : ssize_t write_ret; 329 : data_off_t offset; 330 : unsigned write_size; 331 : - 332 288250 : offset = file_pos * (data_off_t)block_size; + 332 288205 : offset = file_pos * (data_off_t)block_size; 333 : - 334 288250 : write_size = file_block_size(handle->file, file_pos, block_size); + 334 288205 : write_size = file_block_size(handle->file, file_pos, block_size); 335 : 336 : #if HAVE_PWRITE - 337 288250 : write_ret = pwrite(handle->f, block_buffer, write_size, offset); + 337 288205 : write_ret = pwrite(handle->f, block_buffer, write_size, offset); 338 : #else 339 : if (lseek(handle->f, offset, SEEK_SET) != offset) { 340 : /* LCOV_EXCL_START */ @@ -407,7 +407,7 @@ 345 : 346 : write_ret = write(handle->f, block_buffer, write_size); 347 : #endif - 348 288250 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */ + 348 288205 : if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */ 349 : /* LCOV_EXCL_START */ 350 : log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno)); 351 : return -1; @@ -415,34 +415,34 @@ 353 : } 354 : 355 : /* adjust the size of the valid data */ - 356 288250 : if (handle->valid_size < offset + write_size) { - 357 282146 : handle->valid_size = offset + write_size; + 356 288205 : if (handle->valid_size < offset + write_size) { + 357 282174 : handle->valid_size = offset + write_size; 358 : } 359 : 360 : /* Here doesn't make sense to call posix_fadvise(..., POSIX_FADV_DONTNEED) because */ 361 : /* at this time the data is still not yet written and it cannot be discharged. */ 362 : - 363 288250 : return 0; + 363 288205 : return 0; 364 : } 365 : - 366 117835 : int handle_utime(struct snapraid_handle* handle) + 366 117763 : int handle_utime(struct snapraid_handle* handle) 367 : { 368 : int ret; 369 : 370 : /* do nothing if not opened */ - 371 117835 : if (handle->f == -1) + 371 117763 : if (handle->f == -1) 372 0 : return 0; 373 : - 374 117835 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec); + 374 117763 : ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec); 375 : - 376 117835 : if (ret != 0) { + 376 117763 : if (ret != 0) { 377 : /* LCOV_EXCL_START */ 378 : log_fatal("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno)); 379 : return -1; 380 : /* LCOV_EXCL_STOP */ 381 : } 382 : - 383 117835 : return 0; + 383 117763 : return 0; 384 : } 385 : 386 206 : struct snapraid_handle* handle_map(struct snapraid_state* state, unsigned* handlemax) diff --git a/cov/cmdline/import.c.func-sort-c.html b/cov/cmdline/import.c.func-sort-c.html index 6875e443..4ed3e003 100644 --- a/cov/cmdline/import.c.func-sort-c.html +++ b/cov/cmdline/import.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 @@ -61,11 +61,11 @@ import_block_hash - 653410 + 652942 state_import_fetch - 644466 + 643998 import_block_prevhash_compare diff --git a/cov/cmdline/import.c.func.html b/cov/cmdline/import.c.func.html index ab8a545a..00f16958 100644 --- a/cov/cmdline/import.c.func.html +++ b/cov/cmdline/import.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 @@ -61,7 +61,7 @@ import_block_hash - 653410 + 652942 import_block_hash_compare @@ -89,7 +89,7 @@ state_import_fetch - 644466 + 643998
diff --git a/cov/cmdline/import.c.gcov.html b/cov/cmdline/import.c.gcov.html index 80f00c7d..0cec9c66 100644 --- a/cov/cmdline/import.c.gcov.html +++ b/cov/cmdline/import.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 @@ -108,9 +108,9 @@ 46 : * Compute the hash of the hash for an import block. 47 : * We just use the first 32 bit of the hash itself. 48 : */ - 49 653410 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash) + 49 652942 : static inline tommy_uint32_t import_block_hash(const unsigned char* hash) 50 : { - 51 653410 : return *(const tommy_uint32_t*)hash; + 51 652942 : return *(const tommy_uint32_t*)hash; 52 : } 53 : 54 1750 : static void import_file(struct snapraid_state* state, const char* path, uint64_t size) @@ -211,24 +211,24 @@ 149 1750 : free(file); 150 1750 : } 151 : - 152 644466 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer) + 152 643998 : int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer) 153 : { 154 : struct snapraid_import_block* block; 155 : int ret; 156 : int f; - 157 644466 : const unsigned char* hash = missing_block->hash; - 158 644466 : unsigned block_size = state->block_size; + 157 643998 : const unsigned char* hash = missing_block->hash; + 158 643998 : unsigned block_size = state->block_size; 159 : unsigned read_size; 160 : unsigned char buffer_hash[HASH_SIZE]; 161 : const char* path; 162 : - 163 644466 : if (rehash) { - 164 28985 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash)); + 163 643998 : if (rehash) { + 164 28986 : block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash)); 165 : } else { - 166 615481 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash)); + 166 615012 : block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash)); 167 : } - 168 644466 : if (!block) - 169 639994 : return -1; + 168 643998 : if (!block) + 169 639526 : return -1; 170 : 171 4472 : path = block->file->path; 172 4472 : read_size = block->size; diff --git a/cov/cmdline/index-sort-f.html b/cov/cmdline/index-sort-f.html index 9552eb6b..7e050b55 100644 --- a/cov/cmdline/index-sort-f.html +++ b/cov/cmdline/index-sort-f.html @@ -31,13 +31,13 @@ lcov.info Lines: - 7341 - 8031 + 7344 + 8033 91.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 388 @@ -112,20 +112,20 @@ elem.c -
93.6%93.6%
+
93.8%93.8%
- 93.6 % - 537 / 574 - 96.8 % - 61 / 63 + 93.8 % + 545 / 581 + 96.9 % + 62 / 64 state.c -
92.5%92.5%
+
92.4%92.4%
- 92.5 % - 1249 / 1351 + 92.4 % + 1248 / 1351 97.2 % 35 / 36 @@ -382,10 +382,10 @@ scan.c -
87.3%87.3%
+
87.4%87.4%
- 87.3 % - 543 / 622 + 87.4 % + 542 / 620 100.0 % 23 / 23 @@ -402,12 +402,12 @@ elem.h -
99.2%99.2%
+
99.1%99.1%
- 99.2 % - 118 / 119 + 99.1 % + 115 / 116 100.0 % - 40 / 40 + 39 / 39 diff --git a/cov/cmdline/index-sort-l.html b/cov/cmdline/index-sort-l.html index 65ec8595..8aa34497 100644 --- a/cov/cmdline/index-sort-l.html +++ b/cov/cmdline/index-sort-l.html @@ -31,13 +31,13 @@ lcov.info Lines: - 7341 - 8031 + 7344 + 8033 91.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 388 @@ -132,10 +132,10 @@ scan.c -
87.3%87.3%
+
87.4%87.4%
- 87.3 % - 543 / 622 + 87.4 % + 542 / 620 100.0 % 23 / 23 @@ -172,10 +172,10 @@ state.c -
92.5%92.5%
+
92.4%92.4%
- 92.5 % - 1249 / 1351 + 92.4 % + 1248 / 1351 97.2 % 35 / 36 @@ -232,12 +232,12 @@ elem.c -
93.6%93.6%
+
93.8%93.8%
- 93.6 % - 537 / 574 - 96.8 % - 61 / 63 + 93.8 % + 545 / 581 + 96.9 % + 62 / 64 snapraid.c @@ -322,12 +322,12 @@ elem.h -
99.2%99.2%
+
99.1%99.1%
- 99.2 % - 118 / 119 + 99.1 % + 115 / 116 100.0 % - 40 / 40 + 39 / 39 speed.c diff --git a/cov/cmdline/index.html b/cov/cmdline/index.html index c926b667..8449d375 100644 --- a/cov/cmdline/index.html +++ b/cov/cmdline/index.html @@ -31,13 +31,13 @@ lcov.info Lines: - 7341 - 8031 + 7344 + 8033 91.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 388 @@ -112,22 +112,22 @@ elem.c -
93.6%93.6%
+
93.8%93.8%
- 93.6 % - 537 / 574 - 96.8 % - 61 / 63 + 93.8 % + 545 / 581 + 96.9 % + 62 / 64 elem.h -
99.2%99.2%
+
99.1%99.1%
- 99.2 % - 118 / 119 + 99.1 % + 115 / 116 100.0 % - 40 / 40 + 39 / 39 handle.c @@ -242,10 +242,10 @@ scan.c -
87.3%87.3%
+
87.4%87.4%
- 87.3 % - 543 / 622 + 87.4 % + 542 / 620 100.0 % 23 / 23 @@ -312,10 +312,10 @@ state.c -
92.5%92.5%
+
92.4%92.4%
- 92.5 % - 1249 / 1351 + 92.4 % + 1248 / 1351 97.2 % 35 / 36 diff --git a/cov/cmdline/list.c.func-sort-c.html b/cov/cmdline/list.c.func-sort-c.html index ce4c4732..8a842797 100644 --- a/cov/cmdline/list.c.func-sort-c.html +++ b/cov/cmdline/list.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/list.c.func.html b/cov/cmdline/list.c.func.html index cfba2184..6de816a4 100644 --- a/cov/cmdline/list.c.func.html +++ b/cov/cmdline/list.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/list.c.gcov.html b/cov/cmdline/list.c.gcov.html index 64f07edf..6d26e742 100644 --- a/cov/cmdline/list.c.gcov.html +++ b/cov/cmdline/list.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 @@ -110,34 +110,34 @@ 48 18 : tommy_list_sort(&disk->filelist, file_path_compare); 49 : 50 : /* for each file */ - 51 16996 : for (j = disk->filelist; j != 0; j = j->next) { - 52 16978 : struct snapraid_file* file = j->data; + 51 16998 : for (j = disk->filelist; j != 0; j = j->next) { + 52 16980 : struct snapraid_file* file = j->data; 53 : #if HAVE_LOCALTIME_R 54 : struct tm tm_res; 55 : #endif 56 : struct tm* tm; 57 : time_t t; 58 : - 59 16978 : ++file_count; - 60 16978 : file_size += file->size; + 59 16980 : ++file_count; + 60 16980 : file_size += file->size; 61 : - 62 16978 : log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode); + 62 16980 : log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode); 63 : - 64 16978 : t = file->mtime_sec; + 64 16980 : t = file->mtime_sec; 65 : #if HAVE_LOCALTIME_R - 66 16978 : tm = localtime_r(&t, &tm_res); + 66 16980 : tm = localtime_r(&t, &tm_res); 67 : #else 68 : tm = localtime(&t); 69 : #endif 70 : - 71 16978 : printf("%12" PRIu64 " ", file->size); - 72 16978 : if (tm) { - 73 16978 : printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); - 74 16978 : if (msg_level >= MSG_VERBOSE) - 75 16978 : printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000); - 76 16978 : printf(" "); + 71 16980 : printf("%12" PRIu64 " ", file->size); + 72 16980 : if (tm) { + 73 16980 : printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); + 74 16980 : if (msg_level >= MSG_VERBOSE) + 75 16980 : printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000); + 76 16980 : printf(" "); 77 : } - 78 16978 : printf("%s%s\n", disk->dir, file->sub); + 78 16980 : printf("%s%s\n", disk->dir, file->sub); 79 : } 80 : 81 : /* sort by name */ diff --git a/cov/cmdline/mkstream.c.func-sort-c.html b/cov/cmdline/mkstream.c.func-sort-c.html index bf8063bc..0ef05fdf 100644 --- a/cov/cmdline/mkstream.c.func-sort-c.html +++ b/cov/cmdline/mkstream.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/cmdline/mkstream.c.func.html b/cov/cmdline/mkstream.c.func.html index 1c97fe6c..bd99773d 100644 --- a/cov/cmdline/mkstream.c.func.html +++ b/cov/cmdline/mkstream.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/cmdline/mkstream.c.gcov.html b/cov/cmdline/mkstream.c.gcov.html index b24133fb..f02e9bf5 100644 --- a/cov/cmdline/mkstream.c.gcov.html +++ b/cov/cmdline/mkstream.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/cmdline/mktest.c.func-sort-c.html b/cov/cmdline/mktest.c.func-sort-c.html index e9df362b..60c06d2d 100644 --- a/cov/cmdline/mktest.c.func-sort-c.html +++ b/cov/cmdline/mktest.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 18 @@ -61,23 +61,23 @@ rnd - 50983914 + 50988385 rndnz - 50573376 + 50578180 file_cmp - 146649 + 146608 rndnz_range - 31157 + 31195 rnd_name - 26855 + 26824 cmd_generate @@ -93,19 +93,19 @@ cmd_write - 4738 + 4703 cmd_append - 3179 - - - cmd_truncate - 3173 + 3252 cmd_delete - 3172 + 3155 + + + cmd_truncate + 3151 cmd_damage @@ -121,7 +121,7 @@ cmd_generate_symlink - 946 + 915 main diff --git a/cov/cmdline/mktest.c.func.html b/cov/cmdline/mktest.c.func.html index 8a4ba172..96c88f25 100644 --- a/cov/cmdline/mktest.c.func.html +++ b/cov/cmdline/mktest.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 18 @@ -61,7 +61,7 @@ cmd_append - 3179 + 3252 cmd_change @@ -73,7 +73,7 @@ cmd_delete - 3172 + 3155 cmd_generate @@ -85,15 +85,15 @@ cmd_generate_symlink - 946 + 915 cmd_truncate - 3173 + 3151 cmd_write - 4738 + 4703 fallback @@ -101,7 +101,7 @@ file_cmp - 146649 + 146608 help @@ -113,15 +113,15 @@ rnd - 50983914 + 50988385 rnd_name - 26855 + 26824 rndnz - 50573376 + 50578180 rndnz_damage @@ -129,7 +129,7 @@ rndnz_range - 31157 + 31195
diff --git a/cov/cmdline/mktest.c.gcov.html b/cov/cmdline/mktest.c.gcov.html index 9ec3a9fa..501823e9 100644 --- a/cov/cmdline/mktest.c.gcov.html +++ b/cov/cmdline/mktest.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 18 @@ -89,28 +89,28 @@ 27 : */ 28 : unsigned long long seed = 0; 29 : - 30 50983914 : unsigned rnd(unsigned max) + 30 50988385 : unsigned rnd(unsigned max) 31 : { - 32 50983914 : seed = seed * 6364136223846793005LL + 1442695040888963407LL; + 32 50988385 : seed = seed * 6364136223846793005LL + 1442695040888963407LL; 33 : - 34 50983914 : return (seed >> 32) % max; + 34 50988385 : return (seed >> 32) % max; 35 : } 36 : - 37 50573376 : unsigned rndnz(unsigned max) + 37 50578180 : unsigned rndnz(unsigned max) 38 : { - 39 50573376 : if (max <= 1) + 39 50578180 : if (max <= 1) 40 2831 : return 1; 41 : else - 42 50570545 : return rnd(max - 1) + 1; + 42 50575349 : return rnd(max - 1) + 1; 43 : } 44 : - 45 31157 : void rndnz_range(unsigned char* data, int size) + 45 31195 : void rndnz_range(unsigned char* data, int size) 46 : { 47 : int i; 48 : - 49 50599273 : for (i = 0; i < size; ++i) - 50 50568116 : data[i] = rndnz(256); - 51 31157 : } + 49 50604116 : for (i = 0; i < size; ++i) + 50 50572921 : data[i] = rndnz(256); + 51 31195 : } 52 : 53 1821 : void rndnz_damage(unsigned char* data, int size) 54 : { @@ -121,8 +121,8 @@ 59 : unsigned char c; 60 : 61 : do { - 62 1829 : c = rndnz(256); - 63 1829 : } while (c == data[i]); + 62 1828 : c = rndnz(256); + 63 1828 : } while (c == data[i]); 64 : 65 1821 : data[i] = c; 66 : } @@ -131,23 +131,23 @@ 69 : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+"; 70 : #define CHARSET_LEN (sizeof(CHARSET) - 1) 71 : - 72 26855 : void rnd_name(char* file) + 72 26824 : void rnd_name(char* file) 73 : { - 74 26855 : int l = 1 + rnd(20); + 74 26824 : int l = 1 + rnd(20); 75 : - 76 335689 : while (l) { - 77 281979 : *file++ = CHARSET[rnd(CHARSET_LEN)]; - 78 281979 : --l; + 76 335360 : while (l) { + 77 281712 : *file++ = CHARSET[rnd(CHARSET_LEN)]; + 78 281712 : --l; 79 : } - 80 26855 : *file = 0; - 81 26855 : } + 80 26824 : *file = 0; + 81 26824 : } 82 : 83 : /****************************************************************************/ 84 : /* file */ 85 : - 86 146649 : int file_cmp(const void* a, const void* b) + 86 146608 : int file_cmp(const void* a, const void* b) 87 : { - 88 146649 : return strcmp(a, b); + 88 146608 : return strcmp(a, b); 89 : } 90 : 91 1821 : int fallback(int f, struct stat* st) @@ -259,11 +259,11 @@ 197 : * Create a symlink. 198 : * - If the file already exists, it's removed. 199 : */ - 200 946 : void cmd_generate_symlink(const char* path, const char* linkto) + 200 915 : void cmd_generate_symlink(const char* path, const char* linkto) 201 : { 202 : /* remove the existing file/symlink if any */ - 203 946 : if (remove(path) != 0) { - 204 925 : if (errno != ENOENT) { + 203 915 : if (remove(path) != 0) { + 204 894 : if (errno != ENOENT) { 205 : /* LCOV_EXCL_START */ 206 : log_fatal("Error removing file %s\n", path); 207 : exit(EXIT_FAILURE); @@ -271,13 +271,13 @@ 209 : } 210 : } 211 : - 212 946 : if (symlink(linkto, path) != 0) { + 212 915 : if (symlink(linkto, path) != 0) { 213 : /* LCOV_EXCL_START */ 214 : log_fatal("Error writing symlink %s\n", path); 215 : exit(EXIT_FAILURE); 216 : /* LCOV_EXCL_STOP */ 217 : } - 218 946 : } + 218 915 : } 219 : 220 : /** 221 : * Create a file or a symlink with a random name. @@ -350,68 +350,68 @@ 288 : * - The written data may be equal or not at the already existing one. 289 : * - If it's a symlink nothing is done. 290 : */ - 291 4738 : void cmd_write(const char* path, int size) + 291 4703 : void cmd_write(const char* path, int size) 292 : { 293 : struct stat st; 294 : - 295 4738 : if (lstat(path, &st) != 0) { + 295 4703 : if (lstat(path, &st) != 0) { 296 : /* LCOV_EXCL_START */ 297 : log_fatal("Error accessing %s\n", path); 298 : exit(EXIT_FAILURE); 299 : /* LCOV_EXCL_STOP */ 300 : } 301 : - 302 4738 : if (S_ISREG(st.st_mode)) { + 302 4703 : if (S_ISREG(st.st_mode)) { 303 : unsigned char* data; 304 : off_t off; 305 : int f; 306 : 307 : /* not over the end */ - 308 4711 : if (size > st.st_size) - 309 181 : size = st.st_size; + 308 4676 : if (size > st.st_size) + 309 179 : size = st.st_size; 310 : 311 : /* start at random position inside the file */ - 312 4711 : if (size < st.st_size) - 313 4530 : off = rnd(st.st_size - size); + 312 4676 : if (size < st.st_size) + 313 4496 : off = rnd(st.st_size - size); 314 : else - 315 181 : off = 0; + 315 180 : off = 0; 316 : - 317 4711 : data = malloc(size); + 317 4676 : data = malloc(size); 318 : - 319 4711 : rndnz_range(data, size); + 319 4676 : rndnz_range(data, size); 320 : - 321 4711 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); - 322 4711 : if (f < 0) { + 321 4676 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); + 322 4676 : if (f < 0) { 323 : /* LCOV_EXCL_START */ 324 : log_fatal("Error creating file %s\n", path); 325 : exit(EXIT_FAILURE); 326 : /* LCOV_EXCL_STOP */ 327 : } 328 : - 329 4711 : if (lseek(f, off, SEEK_SET) != off) { + 329 4676 : if (lseek(f, off, SEEK_SET) != off) { 330 : /* LCOV_EXCL_START */ 331 : log_fatal("Error seeking file %s\n", path); 332 : exit(EXIT_FAILURE); 333 : /* LCOV_EXCL_STOP */ 334 : } 335 : - 336 4711 : if (write(f, data, size) != size) { + 336 4676 : if (write(f, data, size) != size) { 337 : /* LCOV_EXCL_START */ 338 : log_fatal("Error writing file %s\n", path); 339 : exit(EXIT_FAILURE); 340 : /* LCOV_EXCL_STOP */ 341 : } 342 : - 343 4711 : if (close(f) != 0) { + 343 4676 : if (close(f) != 0) { 344 : /* LCOV_EXCL_START */ 345 : log_fatal("Error closing file %s\n", path); 346 : exit(EXIT_FAILURE); 347 : /* LCOV_EXCL_STOP */ 348 : } 349 : - 350 4711 : free(data); + 350 4676 : free(data); 351 : } - 352 4738 : } + 352 4703 : } 353 : 354 : /** 355 : * Damage a file. @@ -518,50 +518,50 @@ 456 : * - The file must exist. 457 : * - If it's a symlink nothing is done. 458 : */ - 459 3179 : void cmd_append(const char* path, int size) + 459 3252 : void cmd_append(const char* path, int size) 460 : { 461 : struct stat st; 462 : - 463 3179 : if (lstat(path, &st) != 0) { + 463 3252 : if (lstat(path, &st) != 0) { 464 : /* LCOV_EXCL_START */ 465 : log_fatal("Error accessing %s\n", path); 466 : exit(EXIT_FAILURE); 467 : /* LCOV_EXCL_STOP */ 468 : } 469 : - 470 3179 : if (S_ISREG(st.st_mode)) { + 470 3252 : if (S_ISREG(st.st_mode)) { 471 : unsigned char* data; 472 : int f; 473 : - 474 3179 : data = malloc(size); + 474 3252 : data = malloc(size); 475 : - 476 3179 : rndnz_range(data, size); + 476 3252 : rndnz_range(data, size); 477 : - 478 3179 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW); - 479 3179 : if (f < 0) { + 478 3252 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW); + 479 3252 : if (f < 0) { 480 : /* LCOV_EXCL_START */ 481 : log_fatal("Error opening file %s\n", path); 482 : exit(EXIT_FAILURE); 483 : /* LCOV_EXCL_STOP */ 484 : } 485 : - 486 3179 : if (write(f, data, size) != size) { + 486 3252 : if (write(f, data, size) != size) { 487 : /* LCOV_EXCL_START */ 488 : log_fatal("Error writing file %s\n", path); 489 : exit(EXIT_FAILURE); 490 : /* LCOV_EXCL_STOP */ 491 : } 492 : - 493 3179 : if (close(f) != 0) { + 493 3252 : if (close(f) != 0) { 494 : /* LCOV_EXCL_START */ 495 : log_fatal("Error closing file %s\n", path); 496 : exit(EXIT_FAILURE); 497 : /* LCOV_EXCL_STOP */ 498 : } 499 : - 500 3179 : free(data); + 500 3252 : free(data); 501 : } - 502 3179 : } + 502 3252 : } 503 : 504 : /** 505 : * Truncate a file. @@ -569,69 +569,69 @@ 507 : * - The file is NEVER truncated to 0. 508 : * - If it's a symlink nothing is done. 509 : */ - 510 3173 : void cmd_truncate(const char* path, int size) + 510 3151 : void cmd_truncate(const char* path, int size) 511 : { 512 : struct stat st; 513 : - 514 3173 : if (lstat(path, &st) != 0) { + 514 3151 : if (lstat(path, &st) != 0) { 515 : /* LCOV_EXCL_START */ 516 : log_fatal("Error accessing %s\n", path); 517 : exit(EXIT_FAILURE); 518 : /* LCOV_EXCL_STOP */ 519 : } 520 : - 521 3173 : if (S_ISREG(st.st_mode)) { + 521 3151 : if (S_ISREG(st.st_mode)) { 522 : off_t off; 523 : int f; 524 : 525 : /* if file is empty, just rewrite it */ - 526 3173 : if (st.st_size == 0) { - 527 2 : size = 0; + 526 3151 : if (st.st_size == 0) { + 527 3 : size = 0; 528 : } else { 529 : /* don't truncate files to 0 size to avoid ZERO file size protection */ - 530 3171 : if (size >= st.st_size) - 531 171 : size = st.st_size - 1; + 530 3148 : if (size >= st.st_size) + 531 193 : size = st.st_size - 1; 532 : } 533 : - 534 3173 : off = st.st_size - size; + 534 3151 : off = st.st_size - size; 535 : - 536 3173 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); - 537 3173 : if (f < 0) { + 536 3151 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW); + 537 3151 : if (f < 0) { 538 : /* LCOV_EXCL_START */ 539 : log_fatal("Error opening file %s\n", path); 540 : exit(EXIT_FAILURE); 541 : /* LCOV_EXCL_STOP */ 542 : } 543 : - 544 3173 : if (ftruncate(f, off) != 0) { + 544 3151 : if (ftruncate(f, off) != 0) { 545 : /* LCOV_EXCL_START */ 546 : log_fatal("Error truncating file %s\n", path); 547 : exit(EXIT_FAILURE); 548 : /* LCOV_EXCL_STOP */ 549 : } 550 : - 551 3173 : if (close(f) != 0) { + 551 3151 : if (close(f) != 0) { 552 : /* LCOV_EXCL_START */ 553 : log_fatal("Error closing file %s\n", path); 554 : exit(EXIT_FAILURE); 555 : /* LCOV_EXCL_STOP */ 556 : } 557 : } - 558 3173 : } + 558 3151 : } 559 : 560 : /** 561 : * Delete a file. 562 : * - The file must exist. 563 : */ - 564 3172 : void cmd_delete(const char* path) + 564 3155 : void cmd_delete(const char* path) 565 : { - 566 3172 : if (remove(path) != 0) { + 566 3155 : if (remove(path) != 0) { 567 : /* LCOV_EXCL_START */ 568 : log_fatal("Error removing %s\n", path); 569 : exit(EXIT_FAILURE); 570 : /* LCOV_EXCL_STOP */ 571 : } - 572 3172 : } + 572 3155 : } 573 : 574 : /** 575 : * Change a file. Or deleted/truncated/append/created. @@ -642,20 +642,20 @@ 580 : struct stat st; 581 : 582 13128 : if (!size) - 583 13151 : return; + 583 13152 : return; 584 : - 585 13105 : if (lstat(path, &st) != 0) { + 585 13104 : if (lstat(path, &st) != 0) { 586 : /* LCOV_EXCL_START */ 587 : log_fatal("Error accessing %s\n", path); 588 : exit(EXIT_FAILURE); 589 : /* LCOV_EXCL_STOP */ 590 : } 591 : - 592 13105 : if (S_ISLNK(st.st_mode)) { + 592 13104 : if (S_ISLNK(st.st_mode)) { 593 : /* symlink */ 594 392 : if (rnd(2) == 0) { 595 : /* delete */ - 596 179 : if (remove(path) != 0) { + 596 210 : if (remove(path) != 0) { 597 : /* LCOV_EXCL_START */ 598 : log_fatal("Error removing %s\n", path); 599 : exit(EXIT_FAILURE); @@ -665,30 +665,30 @@ 603 : /* recreate */ 604 : char linkto[PATH_MAX]; 605 : - 606 213 : if (remove(path) != 0) { + 606 182 : if (remove(path) != 0) { 607 : /* LCOV_EXCL_START */ 608 : log_fatal("Error removing %s\n", path); 609 : exit(EXIT_FAILURE); 610 : /* LCOV_EXCL_STOP */ 611 : } 612 : - 613 213 : rnd_name(linkto); + 613 182 : rnd_name(linkto); 614 : - 615 213 : cmd_generate_symlink(path, linkto); + 615 182 : cmd_generate_symlink(path, linkto); 616 : } - 617 12713 : } else if (S_ISREG(st.st_mode)) { + 617 12712 : } else if (S_ISREG(st.st_mode)) { 618 : int r; 619 : - 620 12713 : r = rnd(4); + 620 12712 : r = rnd(4); 621 : - 622 12713 : if (r == 0) { - 623 3189 : cmd_write(path, size); - 624 9524 : } else if (r == 1) { - 625 3179 : cmd_append(path, size); - 626 6345 : } else if (r == 2) { - 627 3173 : cmd_truncate(path, size); + 622 12712 : if (r == 0) { + 623 3154 : cmd_write(path, size); + 624 9558 : } else if (r == 1) { + 625 3252 : cmd_append(path, size); + 626 6306 : } else if (r == 2) { + 627 3151 : cmd_truncate(path, size); 628 : } else { - 629 3172 : cmd_delete(path); + 629 3155 : cmd_delete(path); 630 : } 631 : } 632 : } diff --git a/cov/cmdline/murmur3.c.func-sort-c.html b/cov/cmdline/murmur3.c.func-sort-c.html index e894914b..890c3fb1 100644 --- a/cov/cmdline/murmur3.c.func-sort-c.html +++ b/cov/cmdline/murmur3.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,11 +61,11 @@ fmix32 - 9010320 + 9010328 MurmurHash3_x86_128 - 2252580 + 2252582
diff --git a/cov/cmdline/murmur3.c.func.html b/cov/cmdline/murmur3.c.func.html index 8635275f..749722b4 100644 --- a/cov/cmdline/murmur3.c.func.html +++ b/cov/cmdline/murmur3.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,11 +61,11 @@ MurmurHash3_x86_128 - 2252580 + 2252582 fmix32 - 9010320 + 9010328
diff --git a/cov/cmdline/murmur3.c.gcov.html b/cov/cmdline/murmur3.c.gcov.html index 08078433..b92c0ea0 100644 --- a/cov/cmdline/murmur3.c.gcov.html +++ b/cov/cmdline/murmur3.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -91,14 +91,14 @@ 29 : // domain. The author hereby disclaims copyright to this source code. 30 : 31 : /* Finalization mix - force all bits of a hash block to avalanche */ - 32 9010320 : static inline uint32_t fmix32(uint32_t h) + 32 9010328 : static inline uint32_t fmix32(uint32_t h) 33 : { - 34 9010320 : h ^= h >> 16; - 35 9010320 : h *= 0x85ebca6b; - 36 9010320 : h ^= h >> 13; - 37 9010320 : h *= 0xc2b2ae35; - 38 9010320 : h ^= h >> 16; - 39 9010320 : return h; + 34 9010328 : h ^= h >> 16; + 35 9010328 : h *= 0x85ebca6b; + 36 9010328 : h ^= h >> 13; + 37 9010328 : h *= 0xc2b2ae35; + 38 9010328 : h ^= h >> 16; + 39 9010328 : return h; 40 : } 41 : 42 : /* @@ -137,17 +137,17 @@ 75 : uint32_t c3 = 0x38b34ae5; 76 : uint32_t c4 = 0xa1e38b93; 77 : - 78 2252580 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest) + 78 2252582 : void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest) 79 : { 80 : size_t nblocks; 81 : const uint32_t* blocks; 82 : const uint32_t* end; 83 : size_t size_remainder; 84 : - 85 2252580 : uint32_t h1 = ((const uint32_t*)seed)[0]; - 86 2252580 : uint32_t h2 = ((const uint32_t*)seed)[1]; - 87 2252580 : uint32_t h3 = ((const uint32_t*)seed)[2]; - 88 2252580 : uint32_t h4 = ((const uint32_t*)seed)[3]; + 85 2252582 : uint32_t h1 = ((const uint32_t*)seed)[0]; + 86 2252582 : uint32_t h2 = ((const uint32_t*)seed)[1]; + 87 2252582 : uint32_t h3 = ((const uint32_t*)seed)[2]; + 88 2252582 : uint32_t h4 = ((const uint32_t*)seed)[3]; 89 : 90 : #if WORDS_BIGENDIAN 91 : h1 = util_swap32(h1); @@ -156,16 +156,16 @@ 94 : h4 = util_swap32(h4); 95 : #endif 96 : - 97 2252580 : nblocks = size / 16; - 98 2252580 : blocks = data; - 99 2252580 : end = blocks + nblocks * 4; + 97 2252582 : nblocks = size / 16; + 98 2252582 : blocks = data; + 99 2252582 : end = blocks + nblocks * 4; 100 : 101 : /* body */ - 102 119858362 : while (blocks < end) { - 103 115353202 : uint32_t k1 = blocks[0]; - 104 115353202 : uint32_t k2 = blocks[1]; - 105 115353202 : uint32_t k3 = blocks[2]; - 106 115353202 : uint32_t k4 = blocks[3]; + 102 119857435 : while (blocks < end) { + 103 115352271 : uint32_t k1 = blocks[0]; + 104 115352271 : uint32_t k2 = blocks[1]; + 105 115352271 : uint32_t k3 = blocks[2]; + 106 115352271 : uint32_t k4 = blocks[3]; 107 : 108 : #if WORDS_BIGENDIAN 109 : k1 = util_swap32(k1); @@ -174,71 +174,71 @@ 112 : k4 = util_swap32(k4); 113 : #endif 114 : - 115 115353202 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; + 115 115352271 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; 116 : - 117 115353202 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b; + 117 115352271 : h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b; 118 : - 119 115353202 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; + 119 115352271 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; 120 : - 121 115353202 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747; + 121 115352271 : h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747; 122 : - 123 115353202 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; + 123 115352271 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; 124 : - 125 115353202 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35; + 125 115352271 : h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35; 126 : - 127 115353202 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; + 127 115352271 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; 128 : - 129 115353202 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17; + 129 115352271 : h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17; 130 : - 131 115353202 : blocks += 4; + 131 115352271 : blocks += 4; 132 : } 133 : 134 : /* tail */ - 135 2252580 : size_remainder = size & 15; - 136 2252580 : if (size_remainder != 0) { - 137 848217 : const uint8_t* tail = (const uint8_t*)blocks; + 135 2252582 : size_remainder = size & 15; + 136 2252582 : if (size_remainder != 0) { + 137 848153 : const uint8_t* tail = (const uint8_t*)blocks; 138 : - 139 848217 : uint32_t k1 = 0; - 140 848217 : uint32_t k2 = 0; - 141 848217 : uint32_t k3 = 0; - 142 848217 : uint32_t k4 = 0; + 139 848153 : uint32_t k1 = 0; + 140 848153 : uint32_t k2 = 0; + 141 848153 : uint32_t k3 = 0; + 142 848153 : uint32_t k4 = 0; 143 : - 144 848217 : switch (size_remainder) { - 145 55797 : case 15 : k4 ^= tail[14] << 16; - 146 112943 : case 14 : k4 ^= tail[13] << 8; - 147 170169 : case 13 : k4 ^= tail[12] << 0; - 148 170169 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; - 149 227575 : case 12 : k3 ^= tail[11] << 24; - 150 284886 : case 11 : k3 ^= tail[10] << 16; - 151 341909 : case 10 : k3 ^= tail[ 9] << 8; - 152 400365 : case 9 : k3 ^= tail[ 8] << 0; - 153 400365 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; - 154 458648 : case 8 : k2 ^= tail[ 7] << 24; - 155 512723 : case 7 : k2 ^= tail[ 6] << 16; - 156 569585 : case 6 : k2 ^= tail[ 5] << 8; - 157 624551 : case 5 : k2 ^= tail[ 4] << 0; - 158 624551 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; - 159 680593 : case 4 : k1 ^= tail[ 3] << 24; - 160 735635 : case 3 : k1 ^= tail[ 2] << 16; - 161 791529 : case 2 : k1 ^= tail[ 1] << 8; - 162 848217 : case 1 : k1 ^= tail[ 0] << 0; - 163 848217 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; + 144 848153 : switch (size_remainder) { + 145 55834 : case 15 : k4 ^= tail[14] << 16; + 146 112972 : case 14 : k4 ^= tail[13] << 8; + 147 170132 : case 13 : k4 ^= tail[12] << 0; + 148 170132 : k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4; + 149 227529 : case 12 : k3 ^= tail[11] << 24; + 150 284808 : case 11 : k3 ^= tail[10] << 16; + 151 341803 : case 10 : k3 ^= tail[ 9] << 8; + 152 400242 : case 9 : k3 ^= tail[ 8] << 0; + 153 400242 : k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3; + 154 458531 : case 8 : k2 ^= tail[ 7] << 24; + 155 512645 : case 7 : k2 ^= tail[ 6] << 16; + 156 569544 : case 6 : k2 ^= tail[ 5] << 8; + 157 624516 : case 5 : k2 ^= tail[ 4] << 0; + 158 624516 : k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2; + 159 680502 : case 4 : k1 ^= tail[ 3] << 24; + 160 735518 : case 3 : k1 ^= tail[ 2] << 16; + 161 791435 : case 2 : k1 ^= tail[ 1] << 8; + 162 848153 : case 1 : k1 ^= tail[ 0] << 0; + 163 848153 : k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1; 164 : } 165 : } 166 : 167 : /* finalization */ - 168 2252580 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size; + 168 2252582 : h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size; 169 : - 170 2252580 : h1 += h2; h1 += h3; h1 += h4; - 171 2252580 : h2 += h1; h3 += h1; h4 += h1; + 170 2252582 : h1 += h2; h1 += h3; h1 += h4; + 171 2252582 : h2 += h1; h3 += h1; h4 += h1; 172 : - 173 2252580 : h1 = fmix32(h1); - 174 2252580 : h2 = fmix32(h2); - 175 2252580 : h3 = fmix32(h3); - 176 2252580 : h4 = fmix32(h4); + 173 2252582 : h1 = fmix32(h1); + 174 2252582 : h2 = fmix32(h2); + 175 2252582 : h3 = fmix32(h3); + 176 2252582 : h4 = fmix32(h4); 177 : - 178 2252580 : h1 += h2; h1 += h3; h1 += h4; - 179 2252580 : h2 += h1; h3 += h1; h4 += h1; + 178 2252582 : h1 += h2; h1 += h3; h1 += h4; + 179 2252582 : h2 += h1; h3 += h1; h4 += h1; 180 : 181 : #if WORDS_BIGENDIAN 182 : h1 = util_swap32(h1); @@ -247,11 +247,11 @@ 185 : h4 = util_swap32(h4); 186 : #endif 187 : - 188 2252580 : ((uint32_t*)digest)[0] = h1; - 189 2252580 : ((uint32_t*)digest)[1] = h2; - 190 2252580 : ((uint32_t*)digest)[2] = h3; - 191 2252580 : ((uint32_t*)digest)[3] = h4; - 192 2252580 : } + 188 2252582 : ((uint32_t*)digest)[0] = h1; + 189 2252582 : ((uint32_t*)digest)[1] = h2; + 190 2252582 : ((uint32_t*)digest)[2] = h3; + 191 2252582 : ((uint32_t*)digest)[3] = h4; + 192 2252582 : } 193 : diff --git a/cov/cmdline/nano.c.func-sort-c.html b/cov/cmdline/nano.c.func-sort-c.html index ddd04821..86954774 100644 --- a/cov/cmdline/nano.c.func-sort-c.html +++ b/cov/cmdline/nano.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/nano.c.func.html b/cov/cmdline/nano.c.func.html index 30b1558c..0a3357e1 100644 --- a/cov/cmdline/nano.c.func.html +++ b/cov/cmdline/nano.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/nano.c.gcov.html b/cov/cmdline/nano.c.gcov.html index 491f4805..931ad05d 100644 --- a/cov/cmdline/nano.c.gcov.html +++ b/cov/cmdline/nano.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 @@ -96,13 +96,13 @@ 34 : tommy_node* j; 35 : 36 : /* for all files */ - 37 5723 : for (j = disk->filelist; j != 0; j = j->next) { - 38 5717 : struct snapraid_file* file = j->data; + 37 5724 : for (j = disk->filelist; j != 0; j = j->next) { + 38 5718 : struct snapraid_file* file = j->data; 39 : 40 : /* if the file has a zero nanosecond timestamp */ 41 : /* note that symbolic links are not in the file list */ 42 : /* and then are not processed */ - 43 5717 : if (file->mtime_nsec == 0) { + 43 5718 : if (file->mtime_nsec == 0) { 44 : char path[PATH_MAX]; 45 : struct stat st; 46 : int f; diff --git a/cov/cmdline/parity.c.func-sort-c.html b/cov/cmdline/parity.c.func-sort-c.html index 61e63a23..862a0682 100644 --- a/cov/cmdline/parity.c.func-sort-c.html +++ b/cov/cmdline/parity.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -61,11 +61,11 @@ parity_read - 3488589 + 3488577 parity_write - 505320 + 506040 parity_close diff --git a/cov/cmdline/parity.c.func.html b/cov/cmdline/parity.c.func.html index 210ad1cd..700c0fe6 100644 --- a/cov/cmdline/parity.c.func.html +++ b/cov/cmdline/parity.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -89,7 +89,7 @@ parity_read - 3488589 + 3488577 parity_sync @@ -101,7 +101,7 @@ parity_write - 505320 + 506040
diff --git a/cov/cmdline/parity.c.gcov.html b/cov/cmdline/parity.c.gcov.html index 86619b84..6ebacc6b 100644 --- a/cov/cmdline/parity.c.gcov.html +++ b/cov/cmdline/parity.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -129,8 +129,8 @@ 67 431 : block_off_t block = disk_size(disk); 68 : 69 : /* decrease the block until an used one */ - 70 221703 : while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_get(disk, block - 1))) - 71 220841 : --block; + 70 221700 : while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_get(disk, block - 1))) + 71 220838 : --block; 72 : 73 : /* get the highest value */ 74 431 : if (block > parity_block) @@ -486,15 +486,15 @@ 424 952 : return 0; 425 : } 426 : - 427 505320 : int parity_write(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size) + 427 506040 : int parity_write(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size) 428 : { 429 : ssize_t write_ret; 430 : data_off_t offset; 431 : - 432 505320 : offset = pos * (data_off_t)block_size; + 432 506040 : offset = pos * (data_off_t)block_size; 433 : 434 : #if HAVE_PWRITE - 435 505320 : write_ret = pwrite(parity->f, block_buffer, block_size, offset); + 435 506040 : write_ret = pwrite(parity->f, block_buffer, block_size, offset); 436 : #else 437 : if (lseek(parity->f, offset, SEEK_SET) != offset) { 438 : /* LCOV_EXCL_START */ @@ -509,7 +509,7 @@ 447 : 448 : write_ret = write(parity->f, block_buffer, block_size); 449 : #endif - 450 505320 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */ + 450 506040 : if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */ 451 : /* LCOV_EXCL_START */ 452 : if (errno == ENOSPC) { 453 : log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", parity->path); @@ -521,26 +521,26 @@ 459 : } 460 : 461 : /* adjust the size of the valid data */ - 462 505320 : if (parity->valid_size < offset + block_size) { + 462 506040 : if (parity->valid_size < offset + block_size) { 463 170559 : parity->valid_size = offset + block_size; 464 : } 465 : 466 : /* Here doesn't make sense to call posix_fadvise(..., POSIX_FADV_DONTNEED) because */ 467 : /* at this time the data is still in not yet written and it cannot be discharged. */ 468 : - 469 505320 : return 0; + 469 506040 : return 0; 470 : } 471 : - 472 3488589 : int parity_read(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out) + 472 3488577 : int parity_read(struct snapraid_parity_handle* parity, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out) 473 : { 474 : ssize_t read_ret; 475 : data_off_t offset; 476 : unsigned count; 477 : - 478 3488589 : offset = pos * (data_off_t)block_size; + 478 3488577 : offset = pos * (data_off_t)block_size; 479 : 480 : /* check if we are going to read only not initialized data */ - 481 3488589 : if (offset >= parity->valid_size) { + 481 3488577 : if (offset >= parity->valid_size) { 482 90275 : out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", parity->path, offset); 483 90275 : return -1; 484 : } @@ -554,36 +554,36 @@ 492 : } 493 : #endif 494 : - 495 3398314 : count = 0; + 495 3398302 : count = 0; 496 : do { 497 : 498 : #if HAVE_PREAD - 499 3398314 : read_ret = pread(parity->f, block_buffer + count, block_size - count, offset + count); + 499 3398302 : read_ret = pread(parity->f, block_buffer + count, block_size - count, offset + count); 500 : #else 501 : read_ret = read(parity->f, block_buffer + count, block_size - count); 502 : #endif - 503 3398314 : if (read_ret < 0) { + 503 3398302 : if (read_ret < 0) { 504 : /* LCOV_EXCL_START */ 505 : out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", parity->path, offset + count, block_size - count, strerror(errno)); 506 : return -1; 507 : /* LCOV_EXCL_STOP */ 508 : } - 509 3398314 : if (read_ret == 0) { + 509 3398302 : if (read_ret == 0) { 510 : /* LCOV_EXCL_START */ 511 : out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", parity->path, offset, strerror(errno)); 512 : return -1; 513 : /* LCOV_EXCL_STOP */ 514 : } 515 : - 516 3398314 : count += read_ret; - 517 3398314 : } while (count < block_size); + 516 3398302 : count += read_ret; + 517 3398302 : } while (count < block_size); 518 : 519 : /* Here isn't needed to call posix_fadvise(..., POSIX_FADV_DONTNEED) */ 520 : /* because we already advised sequential access with POSIX_FADV_SEQUENTIAL. */ 521 : /* In Linux 2.6.33 it's enough to ensure that data is not kept in the cache. */ 522 : /* Better to do nothing and save a syscall for each block. */ 523 : - 524 3398314 : return block_size; + 524 3398302 : return block_size; 525 : } 526 : diff --git a/cov/cmdline/pool.c.func-sort-c.html b/cov/cmdline/pool.c.func-sort-c.html index ae0e893b..745f72a1 100644 --- a/cov/cmdline/pool.c.func-sort-c.html +++ b/cov/cmdline/pool.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -61,7 +61,7 @@ make_link - 17567 + 17569 clean_dir diff --git a/cov/cmdline/pool.c.func.html b/cov/cmdline/pool.c.func.html index 7b8e4a5b..6a1d2ec3 100644 --- a/cov/cmdline/pool.c.func.html +++ b/cov/cmdline/pool.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -65,7 +65,7 @@ make_link - 17567 + 17569 state_pool diff --git a/cov/cmdline/pool.c.gcov.html b/cov/cmdline/pool.c.gcov.html index 2cc7b271..233bc037 100644 --- a/cov/cmdline/pool.c.gcov.html +++ b/cov/cmdline/pool.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -107,24 +107,24 @@ 45 : struct dirent* dd; 46 : 47 : /* clear errno to detect erroneous conditions */ - 48 5759 : errno = 0; - 49 5759 : dd = readdir(d); - 50 5759 : if (dd == 0 && errno != 0) { + 48 5760 : errno = 0; + 49 5760 : dd = readdir(d); + 50 5760 : if (dd == 0 && errno != 0) { 51 : /* LCOV_EXCL_START */ 52 : log_fatal("Error reading pool directory '%s'. %s.\n", dir, strerror(errno)); 53 : exit(EXIT_FAILURE); 54 : /* LCOV_EXCL_STOP */ 55 : } - 56 5759 : if (dd == 0 && errno == 0) { + 56 5760 : if (dd == 0 && errno == 0) { 57 5 : break; /* finished */ 58 : } 59 : 60 : /* skip "." and ".." files */ - 61 5754 : name = dd->d_name; - 62 5754 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + 61 5755 : name = dd->d_name; + 62 5755 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) 63 10 : continue; 64 : - 65 5744 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 65 5745 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); 66 : 67 : #if HAVE_STRUCT_DIRENT_D_STAT 68 : /* convert dirent to lstat result */ @@ -142,7 +142,7 @@ 80 : } 81 : #else 82 : /* get lstat info about the file */ - 83 5744 : if (lstat(path_next, &st) != 0) { + 83 5745 : if (lstat(path_next, &st) != 0) { 84 : /* LCOV_EXCL_START */ 85 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); 86 : exit(EXIT_FAILURE); @@ -150,12 +150,12 @@ 88 : } 89 : #endif 90 : - 91 5744 : if (S_ISLNK(st.st_mode)) { + 91 5745 : if (S_ISLNK(st.st_mode)) { 92 : int ret; 93 : 94 : /* delete the link */ - 95 5742 : ret = remove(path_next); - 96 5742 : if (ret < 0) { + 95 5743 : ret = remove(path_next); + 96 5743 : if (ret < 0) { 97 : /* LCOV_EXCL_START */ 98 : log_fatal("Error removing symlink '%s'. %s.\n", path_next, strerror(errno)); 99 : exit(EXIT_FAILURE); @@ -194,7 +194,7 @@ 132 0 : ignored = 1; 133 0 : msg_verbose("Ignoring pool file '%s'\n", path_next); 134 : } - 135 5754 : } + 135 5755 : } 136 : 137 5 : if (closedir(d) != 0) { 138 : /* LCOV_EXCL_START */ @@ -209,7 +209,7 @@ 147 : /** 148 : * Create a link to the specified disk entry. 149 : */ - 150 17567 : static void make_link(const char* pool_dir, const char* share_dir, struct snapraid_disk* disk, const char* sub) + 150 17569 : static void make_link(const char* pool_dir, const char* share_dir, struct snapraid_disk* disk, const char* sub) 151 : { 152 : char path[PATH_MAX]; 153 : char linkto[PATH_MAX]; @@ -217,31 +217,31 @@ 155 : int ret; 156 : 157 : /* make the source path */ - 158 17567 : pathprint(path, sizeof(path), "%s%s", pool_dir, sub); + 158 17569 : pathprint(path, sizeof(path), "%s%s", pool_dir, sub); 159 : 160 : /* make the linkto path */ - 161 17567 : if (share_dir[0] != 0) { + 161 17569 : if (share_dir[0] != 0) { 162 : /* with a shared directory, use it */ - 163 17567 : pathprint(linkto, sizeof(linkto), "%s%s/%s", share_dir, disk->name, sub); + 163 17569 : pathprint(linkto, sizeof(linkto), "%s%s/%s", share_dir, disk->name, sub); 164 : } else { 165 : /* without a share directory, use the local disk paths */ 166 0 : pathprint(linkto, sizeof(linkto), "%s%s", disk->dir, sub); 167 : } 168 : 169 : /* create the ancestor directories */ - 170 17567 : ret = mkancestor(path); - 171 17567 : if (ret != 0) { + 170 17569 : ret = mkancestor(path); + 171 17569 : if (ret != 0) { 172 : /* LCOV_EXCL_START */ 173 : exit(EXIT_FAILURE); 174 : /* LCOV_EXCL_STOP */ 175 : } 176 : 177 : /* convert back slashes */ - 178 17567 : pathexport(linkto_exported, sizeof(linkto_exported), linkto); + 178 17569 : pathexport(linkto_exported, sizeof(linkto_exported), linkto); 179 : 180 : /* create the symlink */ - 181 17567 : ret = symlink(linkto_exported, path); - 182 17567 : if (ret != 0) { + 181 17569 : ret = symlink(linkto_exported, path); + 182 17569 : if (ret != 0) { 183 517 : if (errno == EEXIST) { 184 517 : log_fatal("WARNING! Duplicate pooling for '%s'\n", path); 185 : #ifdef _WIN32 @@ -258,7 +258,7 @@ 196 : /* LCOV_EXCL_STOP */ 197 : } 198 : } - 199 17567 : } + 199 17569 : } 200 : 201 3 : void state_pool(struct snapraid_state* state) 202 : { @@ -296,10 +296,10 @@ 234 18 : struct snapraid_disk* disk = i->data; 235 : 236 : /* for each file */ - 237 16996 : for (j = disk->filelist; j != 0; j = j->next) { - 238 16978 : struct snapraid_file* file = j->data; - 239 16978 : make_link(pool_dir, share_dir, disk, file->sub); - 240 16978 : ++count; + 237 16998 : for (j = disk->filelist; j != 0; j = j->next) { + 238 16980 : struct snapraid_file* file = j->data; + 239 16980 : make_link(pool_dir, share_dir, disk, file->sub); + 240 16980 : ++count; 241 : } 242 : 243 : /* for each link */ diff --git a/cov/cmdline/portable.h.func-sort-c.html b/cov/cmdline/portable.h.func-sort-c.html index 465a1c04..4b66bf09 100644 --- a/cov/cmdline/portable.h.func-sort-c.html +++ b/cov/cmdline/portable.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/portable.h.func.html b/cov/cmdline/portable.h.func.html index 6872e429..ee3455ec 100644 --- a/cov/cmdline/portable.h.func.html +++ b/cov/cmdline/portable.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/portable.h.gcov.html b/cov/cmdline/portable.h.gcov.html index 32c8c93d..5cb42125 100644 --- a/cov/cmdline/portable.h.gcov.html +++ b/cov/cmdline/portable.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/rehash.c.func-sort-c.html b/cov/cmdline/rehash.c.func-sort-c.html index 2866182b..7f91b7d7 100644 --- a/cov/cmdline/rehash.c.func-sort-c.html +++ b/cov/cmdline/rehash.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/rehash.c.func.html b/cov/cmdline/rehash.c.func.html index 53664a3e..4f50c788 100644 --- a/cov/cmdline/rehash.c.func.html +++ b/cov/cmdline/rehash.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/rehash.c.gcov.html b/cov/cmdline/rehash.c.gcov.html index cdc16ba4..66b8ba99 100644 --- a/cov/cmdline/rehash.c.gcov.html +++ b/cov/cmdline/rehash.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/cmdline/scan.c.func-sort-c.html b/cov/cmdline/scan.c.func-sort-c.html index 86358b8f..c14fca19 100644 --- a/cov/cmdline/scan.c.func-sort-c.html +++ b/cov/cmdline/scan.c.func-sort-c.html @@ -31,13 +31,13 @@ lcov.info Lines: - 543 - 622 - 87.3 % + 542 + 620 + 87.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 23 @@ -60,59 +60,59 @@ Hit count Sort by hit count - dd_name_compare - 10485267 + dd_name_compare + 10485497 - dstat - 1004147 + dstat + 1004217 - scan_file - 1003012 + scan_file + 1003082 - scan_file_keep - 923695 + scan_file_keep + 923721 - file_is_full_invalid_parity_and_stable - 923695 + file_is_full_invalid_parity_and_stable + 923721 - dd_ino_compare - 103300 + dd_ino_compare + 103314 - scan_file_delayed_allocate - 100930 + scan_file_delayed_allocate + 100975 - scan_file_insert - 100930 + scan_file_insert + 100975 scan_file_allocate - 100930 + 100975 - scan_file_refresh - 79146 + scan_file_refresh + 79190 - scan_file_remove - 56098 + scan_file_remove + 56139 - scan_file_deallocate - 56098 + scan_file_deallocate + 56139 scan_link 32837 - file_is_full_hashed_and_stable + file_is_full_hashed_and_stable 23659 @@ -120,7 +120,7 @@ 2457 - scan_dir + scan_dir 1614 @@ -128,27 +128,27 @@ 956 - scan_emptydir + scan_emptydir 227 - state_diffscan + state_diffscan 80 - state_scan + state_scan 73 - scan_emptydir_insert + scan_emptydir_insert 10 - state_diff + state_diff 7 - scan_emptydir_remove + scan_emptydir_remove 2 diff --git a/cov/cmdline/scan.c.func.html b/cov/cmdline/scan.c.func.html index 7cf7f8dd..abe27914 100644 --- a/cov/cmdline/scan.c.func.html +++ b/cov/cmdline/scan.c.func.html @@ -31,13 +31,13 @@ lcov.info Lines: - 543 - 622 - 87.3 % + 542 + 620 + 87.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 23 @@ -60,72 +60,72 @@ Hit count Sort by hit count - dd_ino_compare - 103300 + dd_ino_compare + 103314 - dd_name_compare - 10485267 + dd_name_compare + 10485497 - dstat - 1004147 + dstat + 1004217 - file_is_full_hashed_and_stable + file_is_full_hashed_and_stable 23659 - file_is_full_invalid_parity_and_stable - 923695 + file_is_full_invalid_parity_and_stable + 923721 - scan_dir + scan_dir 1614 - scan_emptydir + scan_emptydir 227 - scan_emptydir_insert + scan_emptydir_insert 10 - scan_emptydir_remove + scan_emptydir_remove 2 - scan_file - 1003012 + scan_file + 1003082 scan_file_allocate - 100930 + 100975 - scan_file_deallocate - 56098 + scan_file_deallocate + 56139 - scan_file_delayed_allocate - 100930 + scan_file_delayed_allocate + 100975 - scan_file_insert - 100930 + scan_file_insert + 100975 - scan_file_keep - 923695 + scan_file_keep + 923721 - scan_file_refresh - 79146 + scan_file_refresh + 79190 - scan_file_remove - 56098 + scan_file_remove + 56139 scan_link @@ -140,15 +140,15 @@ 956 - state_diff + state_diff 7 - state_diffscan + state_diffscan 80 - state_scan + state_scan 73 diff --git a/cov/cmdline/scan.c.gcov.html b/cov/cmdline/scan.c.gcov.html index a8ad50c7..28c662b0 100644 --- a/cov/cmdline/scan.c.gcov.html +++ b/cov/cmdline/scan.c.gcov.html @@ -31,13 +31,13 @@ lcov.info Lines: - 543 - 622 - 87.3 % + 542 + 620 + 87.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 23 @@ -219,72 +219,72 @@ 157 : /** 158 : * Insert the specified file in the parity. 159 : */ - 160 100930 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file) + 160 100975 : static void scan_file_allocate(struct snapraid_scan* scan, struct snapraid_file* file) 161 : { - 162 100930 : struct snapraid_state* state = scan->state; - 163 100930 : struct snapraid_disk* disk = scan->disk; + 162 100975 : struct snapraid_state* state = scan->state; + 163 100975 : struct snapraid_disk* disk = scan->disk; 164 : block_off_t i; 165 : block_off_t parity_pos; 166 : 167 : /* state changed */ - 168 100930 : state->need_write = 1; + 168 100975 : state->need_write = 1; 169 : 170 : /* allocate the blocks of the file */ - 171 100930 : parity_pos = disk->first_free_block; - 172 349520 : for (i = 0; i < file->blockmax; ++i) { + 171 100975 : parity_pos = disk->first_free_block; + 172 349689 : for (i = 0; i < file->blockmax; ++i) { 173 : struct snapraid_block* block; 174 : struct snapraid_block* over_block; 175 : snapraid_info info; 176 : 177 : /* increment the position until the first really free block */ - 178 1013272 : while (block_has_file(fs_par2block_get(disk, parity_pos))) - 179 516092 : ++parity_pos; + 178 1013456 : while (block_has_file(fs_par2block_get(disk, parity_pos))) + 179 516028 : ++parity_pos; 180 : 181 : /* get block we are going to overwrite, if any */ - 182 248590 : over_block = fs_par2block_get(disk, parity_pos); + 182 248714 : over_block = fs_par2block_get(disk, parity_pos); 183 : 184 : /* deallocate it */ - 185 248590 : if (over_block != BLOCK_EMPTY) - 186 92965 : fs_deallocate(disk, parity_pos); + 185 248714 : if (over_block != BLOCK_EMPTY) + 186 93089 : fs_deallocate(disk, parity_pos); 187 : 188 : /* get block specific info */ - 189 248590 : info = info_get(&state->infoarr, parity_pos); + 189 248714 : info = info_get(&state->infoarr, parity_pos); 190 : 191 : /* get the new block we are going to write */ - 192 248590 : block = fs_file2block_get(file, i); + 192 248714 : block = fs_file2block_get(file, i); 193 : 194 : /* if the file block already has an updated hash without rehash */ - 195 248590 : if (block_has_updated_hash(block) && !info_get_rehash(info)) { + 195 248714 : if (block_has_updated_hash(block) && !info_get_rehash(info)) { 196 : /* the only possible case is for REP blocks */ - 197 37266 : assert(block_state_get(block) == BLOCK_STATE_REP); + 197 37269 : assert(block_state_get(block) == BLOCK_STATE_REP); 198 : 199 : /* convert to a REP block */ - 200 37266 : block_state_set(block, BLOCK_STATE_REP); + 200 37269 : block_state_set(block, BLOCK_STATE_REP); 201 : 202 : /* and keep the hash as it's */ 203 : } else { 204 : unsigned over_state; 205 : 206 : /* convert to a CHG block */ - 207 211324 : block_state_set(block, BLOCK_STATE_CHG); + 207 211445 : block_state_set(block, BLOCK_STATE_CHG); 208 : 209 : /* state of the block we are going to overwrite */ - 210 211324 : over_state = block_state_get(over_block); + 210 211445 : over_state = block_state_get(over_block); 211 : 212 : /* if the block is an empty one */ - 213 211324 : if (over_state == BLOCK_STATE_EMPTY) { + 213 211445 : if (over_state == BLOCK_STATE_EMPTY) { 214 : /* the block was empty and filled with zeros */ 215 : /* set the hash to the special ZERO value */ 216 153288 : hash_zero_set(block->hash); 217 : } else { 218 : /* otherwise it's a DELETED one */ - 219 58036 : assert(over_state == BLOCK_STATE_DELETED); + 219 58157 : assert(over_state == BLOCK_STATE_DELETED); 220 : 221 : /* copy the past hash of the block */ - 222 58036 : memcpy(block->hash, over_block->hash, HASH_SIZE); + 222 58157 : memcpy(block->hash, over_block->hash, HASH_SIZE); 223 : 224 : /* if we have not already cleared the past hash */ - 225 58036 : if (!state->clear_past_hash) { + 225 58157 : if (!state->clear_past_hash) { 226 : /* in this case we don't know if the old state is still the one */ 227 : /* stored inside the parity, because after an aborted sync, the parity */ 228 : /* may be or may be not have been updated with the new data */ @@ -301,1590 +301,1602 @@ 239 : } 240 : 241 : /* store in the disk map, after invalidating all the other blocks */ - 242 248590 : fs_allocate(disk, parity_pos, file, i); + 242 248714 : fs_allocate(disk, parity_pos, file, i); 243 : 244 : /* set the new free position */ - 245 248590 : disk->first_free_block = parity_pos + 1; + 245 248714 : disk->first_free_block = parity_pos + 1; 246 : } 247 : 248 : /* insert in the list of contained files */ - 249 100930 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); - 250 100930 : } + 249 100975 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); + 250 100975 : } 251 : 252 : /** - 253 : * Remove the specified file from the parity. - 254 : * The file is then inserted in the deleted set, and it should no be deallocated. - 255 : */ - 256 56098 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file) - 257 : { - 258 56098 : struct snapraid_state* state = scan->state; - 259 56098 : struct snapraid_disk* disk = scan->disk; - 260 : block_off_t i; - 261 : - 262 : /* remove from the list of contained files */ - 263 56098 : tommy_list_remove_existing(&disk->filelist, &file->nodelist); + 253 : * Delete the specified file from the parity. + 254 : * + 255 : * Note that the parity remains allocated, but the blocks and the file are marked as DELETED. + 256 : * The file is then inserted in the deleted set, and it should not be deallocated, + 257 : * as the parity still references it. + 258 : */ + 259 56139 : static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_file* file) + 260 : { + 261 56139 : struct snapraid_state* state = scan->state; + 262 56139 : struct snapraid_disk* disk = scan->disk; + 263 : block_off_t i; 264 : - 265 : /* state changed */ - 266 56098 : state->need_write = 1; + 265 : /* remove from the list of contained files */ + 266 56139 : tommy_list_remove_existing(&disk->filelist, &file->nodelist); 267 : - 268 : /* free all the blocks of the file */ - 269 194313 : for (i = 0; i < file->blockmax; ++i) { - 270 138215 : struct snapraid_block* block = fs_file2block_get(file, i); - 271 138215 : block_off_t parity_pos = fs_file2par_get(disk, file, i); - 272 : unsigned block_state; - 273 : - 274 : /* adjust the first free position */ - 275 : /* note that doing all the deletions before alllocations, */ - 276 : /* first_free_block is always 0 and the "if" is never triggered */ - 277 : /* but we keep this code anyway for completeness. */ - 278 138215 : if (disk->first_free_block > parity_pos) - 279 0 : disk->first_free_block = parity_pos; - 280 : - 281 : /* in case we scan after an aborted sync, */ - 282 : /* we could get also intermediate states */ - 283 138215 : block_state = block_state_get(block); - 284 138215 : switch (block_state) { - 285 : case BLOCK_STATE_BLK : - 286 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */ - 287 33420 : break; - 288 : case BLOCK_STATE_CHG : - 289 : /* if we have not already cleared the past hash */ - 290 57596 : if (!state->clear_past_hash) { - 291 : /* in these cases we don't know if the old state is still the one */ - 292 : /* stored inside the parity, because after an aborted sync, the parity */ - 293 : /* may be or may be not have been updated with the data that it's now */ - 294 : /* deleted. Then we reset the hash to a bogus value. */ - 295 : /* For example: */ - 296 : /* - One file is added */ - 297 : /* - Sync aborted after updating the parity to the new state, */ - 298 : /* but without saving the content file representing this new state. */ - 299 : /* - File is now deleted after the aborted sync */ - 300 : /* - Sync again, deleting the blocks (exactly here) */ - 301 : /* with the hash of CHG block not represeting the real parity state */ - 302 0 : hash_invalid_set(block->hash); - 303 : } - 304 57596 : break; - 305 : case BLOCK_STATE_REP : - 306 : /* we just don't know the old hash, and then we set it to invalid */ - 307 47199 : hash_invalid_set(block->hash); - 308 47199 : break; - 309 : default : - 310 : /* LCOV_EXCL_START */ - 311 : log_fatal("Internal inconsistency in deallocating for block %u state %u\n", parity_pos, block_state); - 312 : exit(EXIT_FAILURE); - 313 : /* LCOV_EXCL_STOP */ - 314 : } - 315 : - 316 : /* set the block as deleted */ - 317 138215 : block_state_set(block, BLOCK_STATE_DELETED); - 318 : } - 319 : - 320 : /* mark the file as deleted */ - 321 56098 : file_flag_set(file, FILE_IS_DELETED); - 322 : - 323 : /* insert it in the list of deleted blocks */ - 324 56098 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file); - 325 56098 : } - 326 : - 327 100930 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file) - 328 : { - 329 100930 : struct snapraid_state* state = scan->state; - 330 100930 : struct snapraid_disk* disk = scan->disk; - 331 : - 332 : /* if we sort for physical offsets we have to read them for new files */ - 333 100930 : if (state->opt.force_order == SORT_PHYSICAL - 334 11430 : && file->physical == FILEPHY_UNREAD_OFFSET - 335 : ) { - 336 : char path_next[PATH_MAX]; + 268 : /* state changed */ + 269 56139 : state->need_write = 1; + 270 : + 271 : /* here we are supposed to adjust the ::first_free_block position */ + 272 : /* with the parity position we are deleting */ + 273 : /* but we also know that we do only delayed insert, after all the deletion, */ + 274 : /* so at this point ::first_free_block is always at 0, and we don't need to update it */ + 275 56139 : if (disk->first_free_block != 0) { + 276 : /* LCOV_EXCL_START */ + 277 : log_fatal("Internal inconsistency for first free position at '%u' deallocating file '%s'\n", disk->first_free_block, file->sub); + 278 : exit(EXIT_FAILURE); + 279 : /* LCOV_EXCL_STOP */ + 280 : } + 281 : + 282 : /* free all the blocks of the file */ + 283 194478 : for (i = 0; i < file->blockmax; ++i) { + 284 138339 : struct snapraid_block* block = fs_file2block_get(file, i); + 285 : unsigned block_state; + 286 : + 287 : /* in case we scan after an aborted sync, */ + 288 : /* we could get also intermediate states */ + 289 138339 : block_state = block_state_get(block); + 290 138339 : switch (block_state) { + 291 : case BLOCK_STATE_BLK : + 292 : /* we keep the hash making it an "old" hash, because the parity is still containing data for it */ + 293 33544 : break; + 294 : case BLOCK_STATE_CHG : + 295 : /* if we have not already cleared the past hash */ + 296 57596 : if (!state->clear_past_hash) { + 297 : /* in these cases we don't know if the old state is still the one */ + 298 : /* stored inside the parity, because after an aborted sync, the parity */ + 299 : /* may be or may be not have been updated with the data that it's now */ + 300 : /* deleted. Then we reset the hash to a bogus value. */ + 301 : /* For example: */ + 302 : /* - One file is added */ + 303 : /* - Sync aborted after updating the parity to the new state, */ + 304 : /* but without saving the content file representing this new state. */ + 305 : /* - File is now deleted after the aborted sync */ + 306 : /* - Sync again, deleting the blocks (exactly here) */ + 307 : /* with the hash of CHG block not represeting the real parity state */ + 308 0 : hash_invalid_set(block->hash); + 309 : } + 310 57596 : break; + 311 : case BLOCK_STATE_REP : + 312 : /* we just don't know the old hash, and then we set it to invalid */ + 313 47199 : hash_invalid_set(block->hash); + 314 47199 : break; + 315 : default : + 316 : /* LCOV_EXCL_START */ + 317 : log_fatal("Internal inconsistency in file '%s' deallocating block '%u:%u' state %u\n", file->sub, i, file->blockmax, block_state); + 318 : exit(EXIT_FAILURE); + 319 : /* LCOV_EXCL_STOP */ + 320 : } + 321 : + 322 : /* set the block as deleted */ + 323 138339 : block_state_set(block, BLOCK_STATE_DELETED); + 324 : } + 325 : + 326 : /* mark the file as deleted */ + 327 56139 : file_flag_set(file, FILE_IS_DELETED); + 328 : + 329 : /* insert it in the list of deleted blocks */ + 330 56139 : tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file); + 331 56139 : } + 332 : + 333 100975 : static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file) + 334 : { + 335 100975 : struct snapraid_state* state = scan->state; + 336 100975 : struct snapraid_disk* disk = scan->disk; 337 : - 338 11430 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, file->sub); - 339 : - 340 11430 : if (filephy(path_next, file->size, &file->physical) != 0) { - 341 : /* LCOV_EXCL_START */ - 342 : log_fatal("Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno)); - 343 : exit(EXIT_FAILURE); - 344 : /* LCOV_EXCL_STOP */ - 345 : } - 346 : } - 347 : - 348 : /* insert in the delayed list */ - 349 100930 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file); - 350 100930 : } - 351 : - 352 : /** - 353 : * Check if a file is completely formed of blocks with invalid parity, - 354 : * and no rehash is tagged, and if it has at least one block. - 355 : */ - 356 923695 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file) - 357 : { - 358 : block_off_t i; - 359 : - 360 : /* with no block, it never has an invalid parity */ - 361 923695 : if (file->blockmax == 0) - 362 1224 : return 0; - 363 : - 364 : /* check all blocks */ - 365 976103 : for (i = 0; i < file->blockmax; ++i) { - 366 : snapraid_info info; - 367 954319 : struct snapraid_block* block = fs_file2block_get(file, i); - 368 : block_off_t parity_pos; + 338 : /* if we sort for physical offsets we have to read them for new files */ + 339 100975 : if (state->opt.force_order == SORT_PHYSICAL + 340 11432 : && file->physical == FILEPHY_UNREAD_OFFSET + 341 : ) { + 342 : char path_next[PATH_MAX]; + 343 : + 344 11432 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, file->sub); + 345 : + 346 11432 : if (filephy(path_next, file->size, &file->physical) != 0) { + 347 : /* LCOV_EXCL_START */ + 348 : log_fatal("Error in getting the physical offset of file '%s'. %s.\n", path_next, strerror(errno)); + 349 : exit(EXIT_FAILURE); + 350 : /* LCOV_EXCL_STOP */ + 351 : } + 352 : } + 353 : + 354 : /* insert in the delayed list */ + 355 100975 : tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file); + 356 100975 : } + 357 : + 358 : /** + 359 : * Check if a file is completely formed of blocks with invalid parity, + 360 : * and no rehash is tagged, and if it has at least one block. + 361 : */ + 362 923721 : static int file_is_full_invalid_parity_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file) + 363 : { + 364 : block_off_t i; + 365 : + 366 : /* with no block, it never has an invalid parity */ + 367 923721 : if (file->blockmax == 0) + 368 1290 : return 0; 369 : - 370 : /* exclude blocks with parity */ - 371 954319 : if (!block_has_invalid_parity(block)) - 372 900687 : return 0; - 373 : - 374 : /* - 375 : * Get the parity position, but only after checking - 376 : * that the file has invalid parity. - 377 : * This is not really required, as we are sure - 378 : * that 'kept" files are mapped into parity. - 379 : */ - 380 53632 : parity_pos = fs_file2par_get(disk, file, i); - 381 : - 382 : /* get block specific info */ - 383 53632 : info = info_get(&state->infoarr, parity_pos); - 384 : - 385 : /* if rehash fails */ - 386 53632 : if (info_get_rehash(info)) - 387 0 : return 0; - 388 : } - 389 : - 390 21784 : return 1; - 391 : } - 392 : - 393 : /** - 394 : * Check if a file is completely formed of blocks with an updated hash, - 395 : * and no rehash is tagged, and if it has at least one block. - 396 : */ - 397 23659 : static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file) - 398 : { - 399 : block_off_t i; - 400 : - 401 : /* with no block, it never has a hash */ - 402 23659 : if (file->blockmax == 0) - 403 27 : return 0; - 404 : - 405 : /* check all blocks */ - 406 42158 : for (i = 0; i < file->blockmax; ++i) { - 407 : snapraid_info info; - 408 35949 : struct snapraid_block* block = fs_file2block_get(file, i); - 409 : block_off_t parity_pos; + 370 : /* check all blocks */ + 371 976066 : for (i = 0; i < file->blockmax; ++i) { + 372 : snapraid_info info; + 373 954281 : struct snapraid_block* block = fs_file2block_get(file, i); + 374 : block_off_t parity_pos; + 375 : + 376 : /* exclude blocks with parity */ + 377 954281 : if (!block_has_invalid_parity(block)) + 378 900646 : return 0; + 379 : + 380 : /* + 381 : * Get the parity position, but only after checking + 382 : * that the file has invalid parity. + 383 : * This is not really required, as we are sure + 384 : * that 'kept" files are mapped into parity. + 385 : */ + 386 53635 : parity_pos = fs_file2par_get(disk, file, i); + 387 : + 388 : /* get block specific info */ + 389 53635 : info = info_get(&state->infoarr, parity_pos); + 390 : + 391 : /* if rehash fails */ + 392 53635 : if (info_get_rehash(info)) + 393 0 : return 0; + 394 : } + 395 : + 396 21785 : return 1; + 397 : } + 398 : + 399 : /** + 400 : * Check if a file is completely formed of blocks with an updated hash, + 401 : * and no rehash is tagged, and if it has at least one block. + 402 : */ + 403 23659 : static int file_is_full_hashed_and_stable(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file) + 404 : { + 405 : block_off_t i; + 406 : + 407 : /* with no block, it never has a hash */ + 408 23659 : if (file->blockmax == 0) + 409 27 : return 0; 410 : - 411 : /* exclude blocks without hash */ - 412 35949 : if (!block_has_updated_hash(block)) - 413 1704 : return 0; - 414 : - 415 : /* - 416 : * Get the parity position, but only AFTER checking - 417 : * that the file has an updated hash. - 418 : * This is required because not hashed files may be - 419 : * not yet mapped into parity. - 420 : * - 421 : * This happens when a new file is in the delayed insertion - 422 : * list, and scan finds a copy of it, and it tries to copy - 423 : * the hash info. - 424 : * As just allocated files have only CHG blocks, checking that - 425 : * the hash is updated is enough to exclude such cases. - 426 : */ - 427 34245 : parity_pos = fs_file2par_get(disk, file, i); - 428 : - 429 : /* get block specific info */ - 430 34245 : info = info_get(&state->infoarr, parity_pos); - 431 : - 432 : /* exclude blocks needing a rehash */ - 433 34245 : if (info_get_rehash(info)) - 434 15719 : return 0; - 435 : } - 436 : - 437 6209 : return 1; - 438 : } - 439 : - 440 : /** - 441 : * Refresh the file info. - 442 : * - 443 : * This is needed by Windows as the normal way to list directories may report not - 444 : * updated info. Only the GetFileInformationByHandle() func, called file-by-file, - 445 : * really ensures to return synced info. - 446 : * - 447 : * If this happens, we read also the physical offset, to avoid to read it later. - 448 : */ - 449 79146 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical) - 450 : { - 451 : #if HAVE_LSTAT_SYNC - 452 : struct snapraid_state* state = scan->state; - 453 : struct snapraid_disk* disk = scan->disk; - 454 : - 455 : /* if the st_sync is not set, ensure to get synced info */ - 456 : if (st->st_sync == 0) { - 457 : char path_next[PATH_MAX]; - 458 : struct stat synced_st; - 459 : - 460 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, sub); - 461 : - 462 : /* if we sort for physical offsets we have to read them for new files */ - 463 : if (state->opt.force_order == SORT_PHYSICAL - 464 : && *physical == FILEPHY_UNREAD_OFFSET - 465 : ) { - 466 : /* do nothing, leave the pointer to read the physical offset */ - 467 : } else { - 468 : physical = 0; /* set the pointer to 0 to read nothing */ - 469 : } - 470 : - 471 : if (lstat_sync(path_next, &synced_st, physical) != 0) { - 472 : /* LCOV_EXCL_START */ - 473 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno)); - 474 : exit(EXIT_FAILURE); - 475 : /* LCOV_EXCL_STOP */ - 476 : } - 477 : - 478 : if (st->st_mtime != synced_st.st_mtime - 479 : || st->st_mtimensec != synced_st.st_mtimensec - 480 : ) { - 481 : #ifndef _WIN32 - 482 : /* - 483 : * In Windows having different metadata is expected with open files - 484 : * because the metadata in the directory is updated only when the file - 485 : * is closed. - 486 : * - 487 : * See also: - 488 : * Why is the file size reported incorrectly for files that are still being written to? - 489 : * http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx - 490 : */ - 491 : log_fatal("WARNING! Detected uncached time change for file '%s'\n", sub); - 492 : log_fatal("It's better if you run SnapRAID without other processes running.\n"); - 493 : #endif - 494 : st->st_mtime = synced_st.st_mtime; - 495 : st->st_mtimensec = synced_st.st_mtimensec; - 496 : } - 497 : - 498 : if (st->st_size != synced_st.st_size) { - 499 : #ifndef _WIN32 - 500 : log_fatal("WARNING! Detected uncached size change for file '%s'\n", sub); - 501 : log_fatal("It's better if you run SnapRAID without other processes running.\n"); - 502 : #endif - 503 : st->st_size = synced_st.st_size; - 504 : } - 505 : - 506 : if (st->st_ino != synced_st.st_ino) { - 507 : log_fatal("DANGER! Detected uncached inode change for file '%s'\n", sub); - 508 : log_fatal("Please ensure to run SnapRAID without other processes running.\n"); - 509 : /* at this point, it's too late to change inode */ - 510 : /* and having inconsistent inodes may result to internal failures */ - 511 : /* so, it's better to abort */ - 512 : exit(EXIT_FAILURE); - 513 : } - 514 : } - 515 : #else - 516 : (void)scan; - 517 : (void)sub; - 518 : (void)st; - 519 : (void)physical; - 520 : #endif - 521 79146 : } - 522 : - 523 : /** - 524 : * Insert the file in the data set. - 525 : */ - 526 100930 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file) - 527 : { - 528 100930 : struct snapraid_disk* disk = scan->disk; - 529 : - 530 : /* insert the file in the containers */ - 531 100930 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) - 532 100930 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); - 533 100930 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); - 534 100930 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); + 411 : /* check all blocks */ + 412 42158 : for (i = 0; i < file->blockmax; ++i) { + 413 : snapraid_info info; + 414 35949 : struct snapraid_block* block = fs_file2block_get(file, i); + 415 : block_off_t parity_pos; + 416 : + 417 : /* exclude blocks without hash */ + 418 35949 : if (!block_has_updated_hash(block)) + 419 1704 : return 0; + 420 : + 421 : /* + 422 : * Get the parity position, but only AFTER checking + 423 : * that the file has an updated hash. + 424 : * This is required because not hashed files may be + 425 : * not yet mapped into parity. + 426 : * + 427 : * This happens when a new file is in the delayed insertion + 428 : * list, and scan finds a copy of it, and it tries to copy + 429 : * the hash info. + 430 : * As just allocated files have only CHG blocks, checking that + 431 : * the hash is updated is enough to exclude such cases. + 432 : */ + 433 34245 : parity_pos = fs_file2par_get(disk, file, i); + 434 : + 435 : /* get block specific info */ + 436 34245 : info = info_get(&state->infoarr, parity_pos); + 437 : + 438 : /* exclude blocks needing a rehash */ + 439 34245 : if (info_get_rehash(info)) + 440 15719 : return 0; + 441 : } + 442 : + 443 6209 : return 1; + 444 : } + 445 : + 446 : /** + 447 : * Refresh the file info. + 448 : * + 449 : * This is needed by Windows as the normal way to list directories may report not + 450 : * updated info. Only the GetFileInformationByHandle() func, called file-by-file, + 451 : * really ensures to return synced info. + 452 : * + 453 : * If this happens, we read also the physical offset, to avoid to read it later. + 454 : */ + 455 79190 : static void scan_file_refresh(struct snapraid_scan* scan, const char* sub, struct stat* st, uint64_t* physical) + 456 : { + 457 : #if HAVE_LSTAT_SYNC + 458 : struct snapraid_state* state = scan->state; + 459 : struct snapraid_disk* disk = scan->disk; + 460 : + 461 : /* if the st_sync is not set, ensure to get synced info */ + 462 : if (st->st_sync == 0) { + 463 : char path_next[PATH_MAX]; + 464 : struct stat synced_st; + 465 : + 466 : pathprint(path_next, sizeof(path_next), "%s%s", disk->dir, sub); + 467 : + 468 : /* if we sort for physical offsets we have to read them for new files */ + 469 : if (state->opt.force_order == SORT_PHYSICAL + 470 : && *physical == FILEPHY_UNREAD_OFFSET + 471 : ) { + 472 : /* do nothing, leave the pointer to read the physical offset */ + 473 : } else { + 474 : physical = 0; /* set the pointer to 0 to read nothing */ + 475 : } + 476 : + 477 : if (lstat_sync(path_next, &synced_st, physical) != 0) { + 478 : /* LCOV_EXCL_START */ + 479 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno)); + 480 : exit(EXIT_FAILURE); + 481 : /* LCOV_EXCL_STOP */ + 482 : } + 483 : + 484 : if (st->st_mtime != synced_st.st_mtime + 485 : || st->st_mtimensec != synced_st.st_mtimensec + 486 : ) { + 487 : #ifndef _WIN32 + 488 : /* + 489 : * In Windows having different metadata is expected with open files + 490 : * because the metadata in the directory is updated only when the file + 491 : * is closed. + 492 : * + 493 : * See also: + 494 : * Why is the file size reported incorrectly for files that are still being written to? + 495 : * http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx + 496 : */ + 497 : log_fatal("WARNING! Detected uncached time change for file '%s'\n", sub); + 498 : log_fatal("It's better if you run SnapRAID without other processes running.\n"); + 499 : #endif + 500 : st->st_mtime = synced_st.st_mtime; + 501 : st->st_mtimensec = synced_st.st_mtimensec; + 502 : } + 503 : + 504 : if (st->st_size != synced_st.st_size) { + 505 : #ifndef _WIN32 + 506 : log_fatal("WARNING! Detected uncached size change for file '%s'\n", sub); + 507 : log_fatal("It's better if you run SnapRAID without other processes running.\n"); + 508 : #endif + 509 : st->st_size = synced_st.st_size; + 510 : } + 511 : + 512 : if (st->st_ino != synced_st.st_ino) { + 513 : log_fatal("DANGER! Detected uncached inode change for file '%s'\n", sub); + 514 : log_fatal("Please ensure to run SnapRAID without other processes running.\n"); + 515 : /* at this point, it's too late to change inode */ + 516 : /* and having inconsistent inodes may result to internal failures */ + 517 : /* so, it's better to abort */ + 518 : exit(EXIT_FAILURE); + 519 : } + 520 : } + 521 : #else + 522 : (void)scan; + 523 : (void)sub; + 524 : (void)st; + 525 : (void)physical; + 526 : #endif + 527 79190 : } + 528 : + 529 : /** + 530 : * Insert the file in the data set. + 531 : */ + 532 100975 : static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* file) + 533 : { + 534 100975 : struct snapraid_disk* disk = scan->disk; 535 : - 536 : /* delayed allocation of the parity */ - 537 100930 : scan_file_delayed_allocate(scan, file); - 538 100930 : } - 539 : - 540 : /** - 541 : * Remove the file from the data set. - 542 : * - 543 : * File is then deleted. - 544 : */ - 545 56098 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file) - 546 : { - 547 56098 : struct snapraid_disk* disk = scan->disk; - 548 : - 549 : /* remove the file from the containers */ - 550 56098 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) - 551 56043 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); - 552 56098 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); - 553 56098 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset); + 536 : /* insert the file in the containers */ + 537 100975 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) + 538 100975 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 539 100975 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); + 540 100975 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); + 541 : + 542 : /* delayed allocation of the parity */ + 543 100975 : scan_file_delayed_allocate(scan, file); + 544 100975 : } + 545 : + 546 : /** + 547 : * Remove the file from the data set. + 548 : * + 549 : * File is then deleted. + 550 : */ + 551 56139 : static void scan_file_remove(struct snapraid_scan* scan, struct snapraid_file* file) + 552 : { + 553 56139 : struct snapraid_disk* disk = scan->disk; 554 : - 555 : /* deallocate the file from the parity */ - 556 56098 : scan_file_deallocate(scan, file); - 557 56098 : } - 558 : - 559 : /** - 560 : * Keep the file as it's (or with only a name/inode modification). - 561 : * - 562 : * If the file is kept, nothing has to be done. - 563 : * - 564 : * But if a file contains only blocks with invalid parity, it's reallocated to ensure - 565 : * to always minimize the space used in the parity. - 566 : * - 567 : * This could happen after a failed sync, when some other files are deleted, - 568 : * and then new ones can be moved backward to fill the hole created. - 569 : */ - 570 923695 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file) - 571 : { - 572 923695 : struct snapraid_disk* disk = scan->disk; - 573 : - 574 : /* if the file is full invalid, schedule a reinsert at later stage */ - 575 923695 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) { - 576 21784 : struct snapraid_file* copy = file_dup(file); - 577 : - 578 : /* remove the file */ - 579 21784 : scan_file_remove(scan, file); - 580 : - 581 : /* reinsert the copy in the delayed list */ - 582 21784 : scan_file_insert(scan, copy); - 583 : } - 584 923695 : } - 585 : - 586 : /** - 587 : * Process a file. - 588 : */ - 589 1003012 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical) - 590 : { - 591 1003012 : struct snapraid_state* state = scan->state; - 592 1003012 : struct snapraid_disk* disk = scan->disk; - 593 : struct snapraid_file* file; - 594 : tommy_node* i; - 595 : int is_original_file_size_different_than_zero; - 596 : int is_file_already_present; - 597 : int is_file_reported; - 598 : - 599 : /* - 600 : * If the disk has persistent inodes and UUID, try a search on the past inodes, - 601 : * to detect moved files. - 602 : * - 603 : * For persistent inodes we mean inodes that keep their values when the filesystem - 604 : * is unmounted and remounted. This don't always happen. - 605 : * - 606 : * Cases found are: - 607 : * - Linux FUSE with exFAT driver from https://code.google.com/p/exfat/. - 608 : * Inodes are reassigned at every mount restarting from 1 and incrementing. - 609 : * As worse, the exFAT support in FUSE doesn't use subsecond precision in timestamps - 610 : * making inode collision more easy (exFAT by design supports 10ms precision). - 611 : * - Linux VFAT kernel (3.2) driver. Inodes are fully reassigned at every mount. - 612 : * - 613 : * In such cases, to avoid possible random collisions, it's better to disable the moved - 614 : * file recognition. - 615 : * - 616 : * For persistent UUID we mean that it has the same UUID as before. - 617 : * Otherwise, if the UUID is changed, likely it's a new recreated filesystem, - 618 : * and then the inode have no meaning. - 619 : * - 620 : * Note that to disable the search by past inode, we do this implicitely - 621 : * removing all the past inode before searching for files. - 622 : * This ensures that no file is found with a past inode, but at the same time, - 623 : * it allows to find new files with the same inode, to identify them as hardlinks. - 624 : */ - 625 1003012 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid; - 626 : - 627 : /* always search with the new inode, in the all new inodes found until now, */ - 628 : /* with the eventual presence of also the past inodes */ - 629 1003012 : uint64_t inode = st->st_ino; - 630 : - 631 1003012 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); + 555 : /* remove the file from the containers */ + 556 56139 : if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) + 557 56084 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + 558 56139 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); + 559 56139 : tommy_hashdyn_remove_existing(&disk->stampset, &file->stampset); + 560 : + 561 : /* deallocate the file from the parity */ + 562 56139 : scan_file_deallocate(scan, file); + 563 56139 : } + 564 : + 565 : /** + 566 : * Keep the file as it's (or with only a name/inode modification). + 567 : * + 568 : * If the file is kept, nothing has to be done. + 569 : * + 570 : * But if a file contains only blocks with invalid parity, it's reallocated to ensure + 571 : * to always minimize the space used in the parity. + 572 : * + 573 : * This could happen after a failed sync, when some other files are deleted, + 574 : * and then new ones can be moved backward to fill the hole created. + 575 : */ + 576 923721 : static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_file* file) + 577 : { + 578 923721 : struct snapraid_disk* disk = scan->disk; + 579 : + 580 : /* if the file is full invalid, schedule a reinsert at later stage */ + 581 923721 : if (file_is_full_invalid_parity_and_stable(scan->state, disk, file)) { + 582 21785 : struct snapraid_file* copy = file_dup(file); + 583 : + 584 : /* remove the file */ + 585 21785 : scan_file_remove(scan, file); + 586 : + 587 : /* reinsert the copy in the delayed list */ + 588 21785 : scan_file_insert(scan, copy); + 589 : } + 590 923721 : } + 591 : + 592 : /** + 593 : * Process a file. + 594 : */ + 595 1003082 : static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, struct stat* st, uint64_t physical) + 596 : { + 597 1003082 : struct snapraid_state* state = scan->state; + 598 1003082 : struct snapraid_disk* disk = scan->disk; + 599 : struct snapraid_file* file; + 600 : tommy_node* i; + 601 : int is_original_file_size_different_than_zero; + 602 : int is_file_already_present; + 603 : int is_file_reported; + 604 : + 605 : /* + 606 : * If the disk has persistent inodes and UUID, try a search on the past inodes, + 607 : * to detect moved files. + 608 : * + 609 : * For persistent inodes we mean inodes that keep their values when the filesystem + 610 : * is unmounted and remounted. This don't always happen. + 611 : * + 612 : * Cases found are: + 613 : * - Linux FUSE with exFAT driver from https://code.google.com/p/exfat/. + 614 : * Inodes are reassigned at every mount restarting from 1 and incrementing. + 615 : * As worse, the exFAT support in FUSE doesn't use subsecond precision in timestamps + 616 : * making inode collision more easy (exFAT by design supports 10ms precision). + 617 : * - Linux VFAT kernel (3.2) driver. Inodes are fully reassigned at every mount. + 618 : * + 619 : * In such cases, to avoid possible random collisions, it's better to disable the moved + 620 : * file recognition. + 621 : * + 622 : * For persistent UUID we mean that it has the same UUID as before. + 623 : * Otherwise, if the UUID is changed, likely it's a new recreated filesystem, + 624 : * and then the inode have no meaning. + 625 : * + 626 : * Note that to disable the search by past inode, we do this implicitely + 627 : * removing all the past inode before searching for files. + 628 : * This ensures that no file is found with a past inode, but at the same time, + 629 : * it allows to find new files with the same inode, to identify them as hardlinks. + 630 : */ + 631 1003082 : int has_past_inodes = !disk->has_volatile_inodes && !disk->has_different_uuid && !disk->has_unsupported_uuid; 632 : - 633 : /* identify moved files with past inodes and hardlinks with the new inodes */ - 634 1003012 : if (file) { - 635 : /* check if the file is not changed */ - 636 838372 : if (file->size == st->st_size - 637 826527 : && file->mtime_sec == st->st_mtime - 638 823459 : && (file->mtime_nsec == STAT_NSEC(st) - 639 : /* always accept the stored value if it's STAT_NSEC_INVALID */ - 640 : /* it happens when upgrading from an old version of SnapRAID */ - 641 : /* not yet supporting the nanosecond field */ - 642 3 : || file->mtime_nsec == STAT_NSEC_INVALID - 643 : ) - 644 : ) { - 645 : /* check if multiple files have the same inode */ - 646 823456 : if (file_flag_has(file, FILE_IS_PRESENT)) { - 647 : #if HAVE_STRUCT_STAT_ST_NLINK - 648 171 : if (st->st_nlink <= 1) { - 649 : /* LCOV_EXCL_START */ - 650 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub); - 651 : exit(EXIT_FAILURE); - 652 : /* LCOV_EXCL_STOP */ - 653 : } - 654 : #endif - 655 : /* it's a hardlink */ - 656 171 : scan_link(scan, is_diff, sub, file->sub, FILE_IS_HARDLINK); - 657 171 : return; - 658 : } - 659 : - 660 : /* mark as present */ - 661 823285 : file_flag_set(file, FILE_IS_PRESENT); - 662 : - 663 : /* update the nanoseconds mtime only if different */ - 664 : /* to avoid unneeded updates */ - 665 823285 : if (file->mtime_nsec == STAT_NSEC_INVALID - 666 0 : && STAT_NSEC(st) != file->mtime_nsec - 667 : ) { - 668 0 : file->mtime_nsec = STAT_NSEC(st); - 669 : - 670 : /* we have to save the new mtime */ - 671 0 : state->need_write = 1; - 672 : } - 673 : - 674 823285 : if (strcmp(file->sub, sub) != 0) { - 675 : /* if the path is different, it means a moved file with the same inode */ - 676 155 : ++scan->count_move; - 677 : - 678 155 : log_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub)); - 679 155 : if (is_diff) { - 680 0 : printf("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub); - 681 : } - 682 : - 683 : /* remove from the name set */ - 684 155 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); - 685 : - 686 : /* save the new name */ - 687 155 : file_rename(file, sub); + 633 : /* always search with the new inode, in the all new inodes found until now, */ + 634 : /* with the eventual presence of also the past inodes */ + 635 1003082 : uint64_t inode = st->st_ino; + 636 : + 637 1003082 : file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); + 638 : + 639 : /* identify moved files with past inodes and hardlinks with the new inodes */ + 640 1003082 : if (file) { + 641 : /* check if the file is not changed */ + 642 837733 : if (file->size == st->st_size + 643 826569 : && file->mtime_sec == st->st_mtime + 644 823506 : && (file->mtime_nsec == STAT_NSEC(st) + 645 : /* always accept the stored value if it's STAT_NSEC_INVALID */ + 646 : /* it happens when upgrading from an old version of SnapRAID */ + 647 : /* not yet supporting the nanosecond field */ + 648 2 : || file->mtime_nsec == STAT_NSEC_INVALID + 649 : ) + 650 : ) { + 651 : /* check if multiple files have the same inode */ + 652 823504 : if (file_flag_has(file, FILE_IS_PRESENT)) { + 653 : #if HAVE_STRUCT_STAT_ST_NLINK + 654 171 : if (st->st_nlink <= 1) { + 655 : /* LCOV_EXCL_START */ + 656 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub); + 657 : exit(EXIT_FAILURE); + 658 : /* LCOV_EXCL_STOP */ + 659 : } + 660 : #endif + 661 : /* it's a hardlink */ + 662 171 : scan_link(scan, is_diff, sub, file->sub, FILE_IS_HARDLINK); + 663 171 : return; + 664 : } + 665 : + 666 : /* mark as present */ + 667 823333 : file_flag_set(file, FILE_IS_PRESENT); + 668 : + 669 : /* update the nanoseconds mtime only if different */ + 670 : /* to avoid unneeded updates */ + 671 823333 : if (file->mtime_nsec == STAT_NSEC_INVALID + 672 0 : && STAT_NSEC(st) != file->mtime_nsec + 673 : ) { + 674 0 : file->mtime_nsec = STAT_NSEC(st); + 675 : + 676 : /* we have to save the new mtime */ + 677 0 : state->need_write = 1; + 678 : } + 679 : + 680 823333 : if (strcmp(file->sub, sub) != 0) { + 681 : /* if the path is different, it means a moved file with the same inode */ + 682 155 : ++scan->count_move; + 683 : + 684 155 : log_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub)); + 685 155 : if (is_diff) { + 686 0 : printf("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub); + 687 : } 688 : - 689 : /* reinsert in the name set */ - 690 155 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); + 689 : /* remove from the name set */ + 690 155 : tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); 691 : - 692 : /* we have to save the new name */ - 693 155 : state->need_write = 1; - 694 : } else { - 695 : /* otherwise it's equal */ - 696 823130 : ++scan->count_equal; + 692 : /* save the new name */ + 693 155 : file_rename(file, sub); + 694 : + 695 : /* reinsert in the name set */ + 696 155 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); 697 : - 698 823130 : if (state->opt.gui) { - 699 22555 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub)); - 700 : } - 701 : } - 702 : - 703 : /* mark the file as kept */ - 704 823285 : scan_file_keep(scan, file); - 705 : - 706 : /* nothing more to do */ - 707 823285 : return; - 708 : } - 709 : - 710 : /* here the file matches the inode, but not the other info */ - 711 : /* if could be a modified file with the same name, */ - 712 : /* or a restored/copied file that get assigned a previously used inode, */ - 713 : /* or a filesystem with not persistent inodes */ - 714 : - 715 : /* for sure it cannot be already present */ - 716 14916 : if (file_flag_has(file, FILE_IS_PRESENT)) { - 717 : /* LCOV_EXCL_START */ - 718 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub); - 719 : exit(EXIT_FAILURE); - 720 : /* LCOV_EXCL_STOP */ - 721 : } - 722 : - 723 : /* assume a previously used inode, it's the worst case */ - 724 : /* and we handle it removing the duplicate stored inode. */ - 725 : /* If the file is found by name (not necessarely in this function call), */ - 726 : /* it will have the inode restored, otherwise, it will get removed */ - 727 : - 728 : /* remove from the inode set */ - 729 14916 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); - 730 : - 731 : /* clear the inode */ - 732 : /* this is not really needed for correct functionality */ - 733 : /* because we are going to set FILE_IS_WITHOUT_INODE */ - 734 : /* but it's easier for debugging to have invalid inodes set to 0 */ - 735 14916 : file->inode = 0; + 698 : /* we have to save the new name */ + 699 155 : state->need_write = 1; + 700 : } else { + 701 : /* otherwise it's equal */ + 702 823178 : ++scan->count_equal; + 703 : + 704 823178 : if (state->opt.gui) { + 705 22559 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub)); + 706 : } + 707 : } + 708 : + 709 : /* mark the file as kept */ + 710 823333 : scan_file_keep(scan, file); + 711 : + 712 : /* nothing more to do */ + 713 823333 : return; + 714 : } + 715 : + 716 : /* here the file matches the inode, but not the other info */ + 717 : /* if could be a modified file with the same name, */ + 718 : /* or a restored/copied file that get assigned a previously used inode, */ + 719 : /* or a filesystem with not persistent inodes */ + 720 : + 721 : /* for sure it cannot be already present */ + 722 14229 : if (file_flag_has(file, FILE_IS_PRESENT)) { + 723 : /* LCOV_EXCL_START */ + 724 : log_fatal("Internal inode '%" PRIu64 "' inconsistency for files '%s%s' and '%s%s' matching and already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub); + 725 : exit(EXIT_FAILURE); + 726 : /* LCOV_EXCL_STOP */ + 727 : } + 728 : + 729 : /* assume a previously used inode, it's the worst case */ + 730 : /* and we handle it removing the duplicate stored inode. */ + 731 : /* If the file is found by name (not necessarely in this function call), */ + 732 : /* it will have the inode restored, otherwise, it will get removed */ + 733 : + 734 : /* remove from the inode set */ + 735 14229 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); 736 : - 737 : /* mark as missing inode */ - 738 14916 : file_flag_set(file, FILE_IS_WITHOUT_INODE); - 739 : - 740 : /* go further to find it by name */ - 741 : } + 737 : /* clear the inode */ + 738 : /* this is not really needed for correct functionality */ + 739 : /* because we are going to set FILE_IS_WITHOUT_INODE */ + 740 : /* but it's easier for debugging to have invalid inodes set to 0 */ + 741 14229 : file->inode = 0; 742 : - 743 : /* initialize for later overwrite */ - 744 179556 : is_file_reported = 0; - 745 179556 : is_original_file_size_different_than_zero = 0; - 746 : - 747 : /* then try finding it by name */ - 748 179556 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub)); - 749 : - 750 : /* keep track if the file already exists */ - 751 179556 : is_file_already_present = file != 0; + 743 : /* mark as missing inode */ + 744 14229 : file_flag_set(file, FILE_IS_WITHOUT_INODE); + 745 : + 746 : /* go further to find it by name */ + 747 : } + 748 : + 749 : /* initialize for later overwrite */ + 750 179578 : is_file_reported = 0; + 751 179578 : is_original_file_size_different_than_zero = 0; 752 : - 753 179556 : if (is_file_already_present) { - 754 : /* if the file is without an inode */ - 755 105086 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) { - 756 : /* set it now */ - 757 14861 : file->inode = st->st_ino; + 753 : /* then try finding it by name */ + 754 179578 : file = tommy_hashdyn_search(&disk->pathset, file_path_compare_to_arg, sub, file_path_hash(sub)); + 755 : + 756 : /* keep track if the file already exists */ + 757 179578 : is_file_already_present = file != 0; 758 : - 759 : /* insert in the set */ - 760 14861 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); - 761 : - 762 : /* unmark as missing inode */ - 763 14861 : file_flag_clear(file, FILE_IS_WITHOUT_INODE); - 764 : } else { - 765 : /* here the inode has to be different, otherwise we would have found it before */ - 766 90225 : if (file->inode == st->st_ino) { - 767 : /* LCOV_EXCL_START */ - 768 : log_fatal("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub); - 769 : exit(EXIT_FAILURE); - 770 : /* LCOV_EXCL_STOP */ - 771 : } - 772 : } - 773 : - 774 : /* for sure it cannot be already present */ - 775 105086 : if (file_flag_has(file, FILE_IS_PRESENT)) { - 776 : /* LCOV_EXCL_START */ - 777 : log_fatal("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub); - 778 : exit(EXIT_FAILURE); - 779 : /* LCOV_EXCL_STOP */ - 780 : } - 781 : - 782 : /* check if the file is not changed */ - 783 105086 : if (file->size == st->st_size - 784 104492 : && file->mtime_sec == st->st_mtime - 785 100410 : && (file->mtime_nsec == STAT_NSEC(st) - 786 : /* always accept the stored value if it's STAT_NSEC_INVALID */ - 787 : /* it happens when upgrading from an old version of SnapRAID */ - 788 : /* not yet supporting the nanosecond field */ - 789 0 : || file->mtime_nsec == STAT_NSEC_INVALID - 790 : ) - 791 : ) { - 792 : /* mark as present */ - 793 100410 : file_flag_set(file, FILE_IS_PRESENT); - 794 : - 795 : /* update the nano seconds mtime only if different */ - 796 : /* to avoid unneeded updates */ - 797 100410 : if (file->mtime_nsec == STAT_NSEC_INVALID - 798 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID - 799 : ) { - 800 0 : file->mtime_nsec = STAT_NSEC(st); - 801 : - 802 : /* we have to save the new mtime */ - 803 0 : state->need_write = 1; - 804 : } - 805 : - 806 : /* if when processing the disk we used the past inodes values */ - 807 100410 : if (has_past_inodes) { - 808 : /* if persistent inodes are supported, we are sure that the inode number */ - 809 : /* is now different, because otherwise the file would have been found */ - 810 : /* when searching by inode. */ - 811 : /* if the inode is different, it means a rewritten file with the same path */ - 812 : /* like when restoring a backup that restores also the timestamp */ - 813 100410 : ++scan->count_restore; - 814 : - 815 100410 : log_tag("scan:restore:%s:%s\n", disk->name, esc(sub)); - 816 100410 : if (is_diff) { - 817 0 : printf("restore %s%s\n", disk->dir, sub); - 818 : } - 819 : - 820 : /* remove from the inode set */ - 821 100410 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); - 822 : - 823 : /* save the new inode */ - 824 100410 : file->inode = st->st_ino; + 759 179578 : if (is_file_already_present) { + 760 : /* if the file is without an inode */ + 761 105104 : if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) { + 762 : /* set it now */ + 763 14174 : file->inode = st->st_ino; + 764 : + 765 : /* insert in the set */ + 766 14174 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 767 : + 768 : /* unmark as missing inode */ + 769 14174 : file_flag_clear(file, FILE_IS_WITHOUT_INODE); + 770 : } else { + 771 : /* here the inode has to be different, otherwise we would have found it before */ + 772 90930 : if (file->inode == st->st_ino) { + 773 : /* LCOV_EXCL_START */ + 774 : log_fatal("Internal inconsistency in inode '%" PRIu64 "' for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub); + 775 : exit(EXIT_FAILURE); + 776 : /* LCOV_EXCL_STOP */ + 777 : } + 778 : } + 779 : + 780 : /* for sure it cannot be already present */ + 781 105104 : if (file_flag_has(file, FILE_IS_PRESENT)) { + 782 : /* LCOV_EXCL_START */ + 783 : log_fatal("Internal inconsistency in path for file '%s%s' matching and already present\n", disk->dir, sub); + 784 : exit(EXIT_FAILURE); + 785 : /* LCOV_EXCL_STOP */ + 786 : } + 787 : + 788 : /* check if the file is not changed */ + 789 105104 : if (file->size == st->st_size + 790 104510 : && file->mtime_sec == st->st_mtime + 791 100388 : && (file->mtime_nsec == STAT_NSEC(st) + 792 : /* always accept the stored value if it's STAT_NSEC_INVALID */ + 793 : /* it happens when upgrading from an old version of SnapRAID */ + 794 : /* not yet supporting the nanosecond field */ + 795 0 : || file->mtime_nsec == STAT_NSEC_INVALID + 796 : ) + 797 : ) { + 798 : /* mark as present */ + 799 100388 : file_flag_set(file, FILE_IS_PRESENT); + 800 : + 801 : /* update the nano seconds mtime only if different */ + 802 : /* to avoid unneeded updates */ + 803 100388 : if (file->mtime_nsec == STAT_NSEC_INVALID + 804 0 : && STAT_NSEC(st) != STAT_NSEC_INVALID + 805 : ) { + 806 0 : file->mtime_nsec = STAT_NSEC(st); + 807 : + 808 : /* we have to save the new mtime */ + 809 0 : state->need_write = 1; + 810 : } + 811 : + 812 : /* if when processing the disk we used the past inodes values */ + 813 100388 : if (has_past_inodes) { + 814 : /* if persistent inodes are supported, we are sure that the inode number */ + 815 : /* is now different, because otherwise the file would have been found */ + 816 : /* when searching by inode. */ + 817 : /* if the inode is different, it means a rewritten file with the same path */ + 818 : /* like when restoring a backup that restores also the timestamp */ + 819 100388 : ++scan->count_restore; + 820 : + 821 100388 : log_tag("scan:restore:%s:%s\n", disk->name, esc(sub)); + 822 100388 : if (is_diff) { + 823 0 : printf("restore %s%s\n", disk->dir, sub); + 824 : } 825 : - 826 : /* reinsert in the inode set */ - 827 100410 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 826 : /* remove from the inode set */ + 827 100388 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); 828 : - 829 : /* we have to save the new inode */ - 830 100410 : state->need_write = 1; - 831 : } else { - 832 : /* otherwise it's the case of not persistent inode, where doesn't */ - 833 : /* matter if the inode is different or equal, because they have no */ - 834 : /* meaning, and then we don't even save them */ - 835 0 : ++scan->count_equal; - 836 : - 837 0 : if (state->opt.gui) { - 838 0 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub)); - 839 : } - 840 : } - 841 : - 842 : /* mark the file as kept */ - 843 100410 : scan_file_keep(scan, file); - 844 : - 845 : /* nothing more to do */ - 846 100410 : return; - 847 : } - 848 : - 849 : /* here if the file is changed but with the correct name */ + 829 : /* save the new inode */ + 830 100388 : file->inode = st->st_ino; + 831 : + 832 : /* reinsert in the inode set */ + 833 100388 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 834 : + 835 : /* we have to save the new inode */ + 836 100388 : state->need_write = 1; + 837 : } else { + 838 : /* otherwise it's the case of not persistent inode, where doesn't */ + 839 : /* matter if the inode is different or equal, because they have no */ + 840 : /* meaning, and then we don't even save them */ + 841 0 : ++scan->count_equal; + 842 : + 843 0 : if (state->opt.gui) { + 844 0 : log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub)); + 845 : } + 846 : } + 847 : + 848 : /* mark the file as kept */ + 849 100388 : scan_file_keep(scan, file); 850 : - 851 : /* keep track if the original file was not of zero size */ - 852 4676 : is_original_file_size_different_than_zero = file->size != 0; - 853 : - 854 : /* remove it, and continue to insert it again */ - 855 4676 : scan_file_remove(scan, file); + 851 : /* nothing more to do */ + 852 100388 : return; + 853 : } + 854 : + 855 : /* here if the file is changed but with the correct name */ 856 : - 857 : /* and continue to insert it again */ - 858 : } + 857 : /* keep track if the original file was not of zero size */ + 858 4716 : is_original_file_size_different_than_zero = file->size != 0; 859 : - 860 : /* refresh the info, to ensure that they are synced, */ - 861 : /* note that we refresh only the info of the new or modified files */ - 862 : /* because this is slow operation */ - 863 79146 : scan_file_refresh(scan, sub, st, &physical); - 864 : - 865 : /* do a safety check to ensure that the common ext4 case of zeroing */ - 866 : /* the size of a file after a crash doesn't propagate to the backup */ - 867 79146 : if (is_original_file_size_different_than_zero && st->st_size == 0) { - 868 0 : if (!state->opt.force_zero) { - 869 : /* LCOV_EXCL_START */ - 870 : log_fatal("The file '%s%s' has unexpected zero size!\n", disk->dir, sub); - 871 : log_fatal("It's possible that after a kernel crash this file was lost,\n"); - 872 : log_fatal("and you can use 'snapraid --filter %s fix' to recover it.\n", sub); - 873 : if (!is_diff) { - 874 : log_fatal("If this an expected condition you can '%s' anyway using 'snapraid --force-zero %s'\n", state->command, state->command); - 875 : exit(EXIT_FAILURE); - 876 : } - 877 : /* LCOV_EXCL_STOP */ - 878 : } - 879 : } - 880 : - 881 : /* insert it */ - 882 79146 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical); - 883 : - 884 : /* mark it as present */ - 885 79146 : file_flag_set(file, FILE_IS_PRESENT); - 886 : - 887 : /* if copy detection is enabled */ - 888 : /* note that the copy detection is tried also for updated files */ - 889 : /* this makes sense because it may happen to have two different copies */ - 890 : /* of the same file, and we move the right one over the wrong one */ - 891 : /* in such case we have a "copy" over an "update" */ - 892 79146 : if (!state->opt.force_nocopy) { - 893 79146 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); - 894 : - 895 : /* search for a file with the same name and stamp in all the disks */ - 896 518303 : for (i = state->disklist; i != 0; i = i->next) { - 897 445366 : struct snapraid_disk* other_disk = i->data; - 898 : struct snapraid_file* other_file; - 899 : - 900 : /* if the nanosecond part of the time stamp is valid, search */ - 901 : /* for name and stamp, otherwise for path and stamp */ - 902 445366 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID) - 903 445258 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash); - 904 : else - 905 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash); + 860 : /* remove it, and continue to insert it again */ + 861 4716 : scan_file_remove(scan, file); + 862 : + 863 : /* and continue to insert it again */ + 864 : } + 865 : + 866 : /* refresh the info, to ensure that they are synced, */ + 867 : /* note that we refresh only the info of the new or modified files */ + 868 : /* because this is slow operation */ + 869 79190 : scan_file_refresh(scan, sub, st, &physical); + 870 : + 871 : #ifndef _WIN32 + 872 : /* do a safety check to ensure that the common ext4 case of zeroing */ + 873 : /* the size of a file after a crash doesn't propagate to the backup */ + 874 : /* this check is specific for Linux, so we disable it on Windows */ + 875 79190 : if (is_original_file_size_different_than_zero && st->st_size == 0) { + 876 0 : if (!state->opt.force_zero) { + 877 : /* LCOV_EXCL_START */ + 878 : log_fatal("The file '%s%s' has unexpected zero size!\n", disk->dir, sub); + 879 : log_fatal("It's possible that after a kernel crash this file was lost,\n"); + 880 : log_fatal("and you can use 'snapraid --filter %s fix' to recover it.\n", sub); + 881 : if (!is_diff) { + 882 : log_fatal("If this an expected condition you can '%s' anyway using 'snapraid --force-zero %s'\n", state->command, state->command); + 883 : exit(EXIT_FAILURE); + 884 : } + 885 : /* LCOV_EXCL_STOP */ + 886 : } + 887 : } + 888 : #else + 889 : /* avoid the unused warning in Windows */ + 890 : (void)is_original_file_size_different_than_zero; + 891 : #endif + 892 : + 893 : /* insert it */ + 894 79190 : file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, STAT_NSEC(st), st->st_ino, physical); + 895 : + 896 : /* mark it as present */ + 897 79190 : file_flag_set(file, FILE_IS_PRESENT); + 898 : + 899 : /* if copy detection is enabled */ + 900 : /* note that the copy detection is tried also for updated files */ + 901 : /* this makes sense because it may happen to have two different copies */ + 902 : /* of the same file, and we move the right one over the wrong one */ + 903 : /* in such case we have a "copy" over an "update" */ + 904 79190 : if (!state->opt.force_nocopy) { + 905 79190 : tommy_uint32_t hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); 906 : - 907 : /* if found, and it's a fully hashed file */ - 908 445366 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) { - 909 : /* assume that the file is a copy, and reuse the hash */ - 910 6209 : file_copy(other_file, file); + 907 : /* search for a file with the same name and stamp in all the disks */ + 908 518611 : for (i = state->disklist; i != 0; i = i->next) { + 909 445630 : struct snapraid_disk* other_disk = i->data; + 910 : struct snapraid_file* other_file; 911 : - 912 : /* revert old counter and use the copy one */ - 913 6209 : ++scan->count_copy; - 914 : - 915 6209 : log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub)); - 916 6209 : if (is_diff) { - 917 31 : printf("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub); - 918 : } - 919 : - 920 : /* mark it as reported */ - 921 6209 : is_file_reported = 1; - 922 : - 923 : /* no need to continue the search */ - 924 6209 : break; - 925 : } - 926 : } - 927 : } - 928 : - 929 : /* if not yet reported, do it now */ - 930 79146 : if (!is_file_reported) { - 931 72937 : if (is_file_already_present) { - 932 4676 : ++scan->count_change; - 933 : - 934 4676 : log_tag("scan:update:%s:%s\n", disk->name, esc(sub)); - 935 4676 : if (is_diff) { - 936 118 : printf("update %s%s\n", disk->dir, sub); + 912 : /* if the nanosecond part of the time stamp is valid, search */ + 913 : /* for name and stamp, otherwise for path and stamp */ + 914 445630 : if (file->mtime_nsec != 0 && file->mtime_nsec != STAT_NSEC_INVALID) + 915 445522 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_namestamp_compare, file, hash); + 916 : else + 917 108 : other_file = tommy_hashdyn_search(&other_disk->stampset, file_pathstamp_compare, file, hash); + 918 : + 919 : /* if found, and it's a fully hashed file */ + 920 445630 : if (other_file && file_is_full_hashed_and_stable(scan->state, other_disk, other_file)) { + 921 : /* assume that the file is a copy, and reuse the hash */ + 922 6209 : file_copy(other_file, file); + 923 : + 924 : /* revert old counter and use the copy one */ + 925 6209 : ++scan->count_copy; + 926 : + 927 6209 : log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub)); + 928 6209 : if (is_diff) { + 929 31 : printf("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub); + 930 : } + 931 : + 932 : /* mark it as reported */ + 933 6209 : is_file_reported = 1; + 934 : + 935 : /* no need to continue the search */ + 936 6209 : break; 937 : } - 938 : } else { - 939 68261 : ++scan->count_insert; + 938 : } + 939 : } 940 : - 941 68261 : log_tag("scan:add:%s:%s\n", disk->name, esc(sub)); - 942 68261 : if (is_diff) { - 943 17042 : printf("add %s%s\n", disk->dir, sub); - 944 : } - 945 : } - 946 : } - 947 : - 948 : /* insert the file in the delayed list */ - 949 79146 : scan_file_insert(scan, file); - 950 : } - 951 : - 952 : /** - 953 : * Remove the specified dir from the data set. - 954 : */ - 955 2 : static void scan_emptydir_remove(struct snapraid_scan* scan, struct snapraid_dir* dir) - 956 : { - 957 2 : struct snapraid_state* state = scan->state; - 958 2 : struct snapraid_disk* disk = scan->disk; + 941 : /* if not yet reported, do it now */ + 942 79190 : if (!is_file_reported) { + 943 72981 : if (is_file_already_present) { + 944 4716 : ++scan->count_change; + 945 : + 946 4716 : log_tag("scan:update:%s:%s\n", disk->name, esc(sub)); + 947 4716 : if (is_diff) { + 948 118 : printf("update %s%s\n", disk->dir, sub); + 949 : } + 950 : } else { + 951 68265 : ++scan->count_insert; + 952 : + 953 68265 : log_tag("scan:add:%s:%s\n", disk->name, esc(sub)); + 954 68265 : if (is_diff) { + 955 17044 : printf("add %s%s\n", disk->dir, sub); + 956 : } + 957 : } + 958 : } 959 : - 960 : /* state changed */ - 961 2 : state->need_write = 1; - 962 : - 963 : /* remove the file from the dir containers */ - 964 2 : tommy_hashdyn_remove_existing(&disk->dirset, &dir->nodeset); - 965 2 : tommy_list_remove_existing(&disk->dirlist, &dir->nodelist); - 966 : - 967 : /* deallocate */ - 968 2 : dir_free(dir); - 969 2 : } - 970 : - 971 : /** - 972 : * Insert the specified dir in the data set. - 973 : */ - 974 10 : static void scan_emptydir_insert(struct snapraid_scan* scan, struct snapraid_dir* dir) - 975 : { - 976 10 : struct snapraid_state* state = scan->state; - 977 10 : struct snapraid_disk* disk = scan->disk; + 960 : /* insert the file in the delayed list */ + 961 79190 : scan_file_insert(scan, file); + 962 : } + 963 : + 964 : /** + 965 : * Remove the specified dir from the data set. + 966 : */ + 967 2 : static void scan_emptydir_remove(struct snapraid_scan* scan, struct snapraid_dir* dir) + 968 : { + 969 2 : struct snapraid_state* state = scan->state; + 970 2 : struct snapraid_disk* disk = scan->disk; + 971 : + 972 : /* state changed */ + 973 2 : state->need_write = 1; + 974 : + 975 : /* remove the file from the dir containers */ + 976 2 : tommy_hashdyn_remove_existing(&disk->dirset, &dir->nodeset); + 977 2 : tommy_list_remove_existing(&disk->dirlist, &dir->nodelist); 978 : - 979 : /* state changed */ - 980 10 : state->need_write = 1; - 981 : - 982 : /* insert the dir in the dir containers */ - 983 10 : tommy_hashdyn_insert(&disk->dirset, &dir->nodeset, dir, dir_name_hash(dir->sub)); - 984 10 : tommy_list_insert_tail(&disk->dirlist, &dir->nodelist, dir); - 985 10 : } - 986 : - 987 : /** - 988 : * Process a dir. - 989 : */ - 990 227 : static void scan_emptydir(struct snapraid_scan* scan, const char* sub) - 991 : { - 992 227 : struct snapraid_disk* disk = scan->disk; - 993 : struct snapraid_dir* dir; - 994 : - 995 : /* check if the dir already exists */ - 996 227 : dir = tommy_hashdyn_search(&disk->dirset, dir_name_compare, sub, dir_name_hash(sub)); - 997 227 : if (dir) { - 998 : /* check if multiple files have the same name */ - 999 217 : if (dir_flag_has(dir, FILE_IS_PRESENT)) { - 1000 : /* LCOV_EXCL_START */ - 1001 : log_fatal("Internal inconsistency for dir '%s%s'\n", disk->dir, sub); - 1002 : exit(EXIT_FAILURE); - 1003 : /* LCOV_EXCL_STOP */ - 1004 : } - 1005 : - 1006 : /* mark as present */ - 1007 217 : dir_flag_set(dir, FILE_IS_PRESENT); - 1008 : - 1009 : /* nothing more to do */ - 1010 444 : return; - 1011 : } else { - 1012 : /* and continue to insert it */ - 1013 : } - 1014 : - 1015 : /* insert it */ - 1016 10 : dir = dir_alloc(sub); + 979 : /* deallocate */ + 980 2 : dir_free(dir); + 981 2 : } + 982 : + 983 : /** + 984 : * Insert the specified dir in the data set. + 985 : */ + 986 10 : static void scan_emptydir_insert(struct snapraid_scan* scan, struct snapraid_dir* dir) + 987 : { + 988 10 : struct snapraid_state* state = scan->state; + 989 10 : struct snapraid_disk* disk = scan->disk; + 990 : + 991 : /* state changed */ + 992 10 : state->need_write = 1; + 993 : + 994 : /* insert the dir in the dir containers */ + 995 10 : tommy_hashdyn_insert(&disk->dirset, &dir->nodeset, dir, dir_name_hash(dir->sub)); + 996 10 : tommy_list_insert_tail(&disk->dirlist, &dir->nodelist, dir); + 997 10 : } + 998 : + 999 : /** + 1000 : * Process a dir. + 1001 : */ + 1002 227 : static void scan_emptydir(struct snapraid_scan* scan, const char* sub) + 1003 : { + 1004 227 : struct snapraid_disk* disk = scan->disk; + 1005 : struct snapraid_dir* dir; + 1006 : + 1007 : /* check if the dir already exists */ + 1008 227 : dir = tommy_hashdyn_search(&disk->dirset, dir_name_compare, sub, dir_name_hash(sub)); + 1009 227 : if (dir) { + 1010 : /* check if multiple files have the same name */ + 1011 217 : if (dir_flag_has(dir, FILE_IS_PRESENT)) { + 1012 : /* LCOV_EXCL_START */ + 1013 : log_fatal("Internal inconsistency for dir '%s%s'\n", disk->dir, sub); + 1014 : exit(EXIT_FAILURE); + 1015 : /* LCOV_EXCL_STOP */ + 1016 : } 1017 : - 1018 : /* mark it as present */ - 1019 10 : dir_flag_set(dir, FILE_IS_PRESENT); + 1018 : /* mark as present */ + 1019 217 : dir_flag_set(dir, FILE_IS_PRESENT); 1020 : - 1021 : /* insert it in the delayed insert list */ - 1022 10 : tommy_list_insert_tail(&scan->dir_insert_list, &dir->nodelist, dir); - 1023 : } - 1024 : - 1025 : struct dirent_sorted { - 1026 : /* node for data structures */ - 1027 : tommy_node node; - 1028 : - 1029 : #if HAVE_STRUCT_DIRENT_D_INO - 1030 : uint64_t d_ino; /**< Inode number. */ - 1031 : #endif - 1032 : #if HAVE_STRUCT_DIRENT_D_TYPE - 1033 : uint32_t d_type; /**< File type. */ - 1034 : #endif - 1035 : #if HAVE_STRUCT_DIRENT_D_STAT - 1036 : struct stat d_stat; /**< Stat result. */ - 1037 : #endif - 1038 : char d_name[]; /**< Variable length name. It must be the last field. */ - 1039 : }; - 1040 : + 1021 : /* nothing more to do */ + 1022 444 : return; + 1023 : } else { + 1024 : /* and continue to insert it */ + 1025 : } + 1026 : + 1027 : /* insert it */ + 1028 10 : dir = dir_alloc(sub); + 1029 : + 1030 : /* mark it as present */ + 1031 10 : dir_flag_set(dir, FILE_IS_PRESENT); + 1032 : + 1033 : /* insert it in the delayed insert list */ + 1034 10 : tommy_list_insert_tail(&scan->dir_insert_list, &dir->nodelist, dir); + 1035 : } + 1036 : + 1037 : struct dirent_sorted { + 1038 : /* node for data structures */ + 1039 : tommy_node node; + 1040 : 1041 : #if HAVE_STRUCT_DIRENT_D_INO - 1042 103300 : static int dd_ino_compare(const void* void_a, const void* void_b) - 1043 : { - 1044 103300 : const struct dirent_sorted* a = void_a; - 1045 103300 : const struct dirent_sorted* b = void_b; - 1046 : - 1047 103300 : if (a->d_ino < b->d_ino) - 1048 49394 : return -1; - 1049 53906 : if (a->d_ino > b->d_ino) - 1050 53906 : return 1; - 1051 : - 1052 0 : return 0; - 1053 : } - 1054 : #endif - 1055 : - 1056 10485267 : static int dd_name_compare(const void* void_a, const void* void_b) - 1057 : { - 1058 10485267 : const struct dirent_sorted* a = void_a; - 1059 10485267 : const struct dirent_sorted* b = void_b; - 1060 : - 1061 10485267 : return strcmp(a->d_name, b->d_name); - 1062 : } + 1042 : uint64_t d_ino; /**< Inode number. */ + 1043 : #endif + 1044 : #if HAVE_STRUCT_DIRENT_D_TYPE + 1045 : uint32_t d_type; /**< File type. */ + 1046 : #endif + 1047 : #if HAVE_STRUCT_DIRENT_D_STAT + 1048 : struct stat d_stat; /**< Stat result. */ + 1049 : #endif + 1050 : char d_name[]; /**< Variable length name. It must be the last field. */ + 1051 : }; + 1052 : + 1053 : #if HAVE_STRUCT_DIRENT_D_INO + 1054 103314 : static int dd_ino_compare(const void* void_a, const void* void_b) + 1055 : { + 1056 103314 : const struct dirent_sorted* a = void_a; + 1057 103314 : const struct dirent_sorted* b = void_b; + 1058 : + 1059 103314 : if (a->d_ino < b->d_ino) + 1060 49400 : return -1; + 1061 53914 : if (a->d_ino > b->d_ino) + 1062 53914 : return 1; 1063 : - 1064 : /** - 1065 : * Return the stat info of a dir entry. - 1066 : */ - 1067 : #if HAVE_STRUCT_DIRENT_D_STAT - 1068 : #define DSTAT(file, dd, buf) dstat(dd) - 1069 : struct stat* dstat(struct dirent_sorted* dd) - 1070 : { - 1071 : return &dd->d_stat; - 1072 : } - 1073 : #else - 1074 : #define DSTAT(file, dd, buf) dstat(file, buf) - 1075 1004147 : struct stat* dstat(const char* file, struct stat* st) - 1076 : { - 1077 1004147 : if (lstat(file, st) != 0) { - 1078 : /* LCOV_EXCL_START */ - 1079 : log_fatal("Error in stat file/directory '%s'. %s.\n", file, strerror(errno)); - 1080 : exit(EXIT_FAILURE); - 1081 : /* LCOV_EXCL_STOP */ - 1082 : } - 1083 1004147 : return st; + 1064 0 : return 0; + 1065 : } + 1066 : #endif + 1067 : + 1068 10485497 : static int dd_name_compare(const void* void_a, const void* void_b) + 1069 : { + 1070 10485497 : const struct dirent_sorted* a = void_a; + 1071 10485497 : const struct dirent_sorted* b = void_b; + 1072 : + 1073 10485497 : return strcmp(a->d_name, b->d_name); + 1074 : } + 1075 : + 1076 : /** + 1077 : * Return the stat info of a dir entry. + 1078 : */ + 1079 : #if HAVE_STRUCT_DIRENT_D_STAT + 1080 : #define DSTAT(file, dd, buf) dstat(dd) + 1081 : struct stat* dstat(struct dirent_sorted* dd) + 1082 : { + 1083 : return &dd->d_stat; 1084 : } - 1085 : #endif - 1086 : - 1087 : /** - 1088 : * Process a directory. - 1089 : * Return != 0 if at least one file or link is processed. - 1090 : */ - 1091 1614 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub) - 1092 : { - 1093 1614 : struct snapraid_state* state = scan->state; - 1094 1614 : struct snapraid_disk* disk = scan->disk; - 1095 1614 : int processed = 0; - 1096 : DIR* d; - 1097 : tommy_list list; - 1098 : tommy_node* node; - 1099 : - 1100 1614 : tommy_list_init(&list); - 1101 : - 1102 1614 : d = opendir(dir); - 1103 1614 : if (!d) { - 1104 : /* LCOV_EXCL_START */ - 1105 : log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno)); - 1106 : if (level == 0) - 1107 : log_fatal("If this is the disk mount point, remember to create it manually\n"); - 1108 : else - 1109 : log_fatal("If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub); - 1110 : exit(EXIT_FAILURE); - 1111 : /* LCOV_EXCL_STOP */ - 1112 : } + 1085 : #else + 1086 : #define DSTAT(file, dd, buf) dstat(file, buf) + 1087 1004217 : struct stat* dstat(const char* file, struct stat* st) + 1088 : { + 1089 1004217 : if (lstat(file, st) != 0) { + 1090 : /* LCOV_EXCL_START */ + 1091 : log_fatal("Error in stat file/directory '%s'. %s.\n", file, strerror(errno)); + 1092 : exit(EXIT_FAILURE); + 1093 : /* LCOV_EXCL_STOP */ + 1094 : } + 1095 1004217 : return st; + 1096 : } + 1097 : #endif + 1098 : + 1099 : /** + 1100 : * Process a directory. + 1101 : * Return != 0 if at least one file or link is processed. + 1102 : */ + 1103 1614 : static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const char* dir, const char* sub) + 1104 : { + 1105 1614 : struct snapraid_state* state = scan->state; + 1106 1614 : struct snapraid_disk* disk = scan->disk; + 1107 1614 : int processed = 0; + 1108 : DIR* d; + 1109 : tommy_list list; + 1110 : tommy_node* node; + 1111 : + 1112 1614 : tommy_list_init(&list); 1113 : - 1114 : /* read the full directory */ - 1115 : while (1) { - 1116 : char path_next[PATH_MAX]; - 1117 : char sub_next[PATH_MAX]; - 1118 : struct dirent_sorted* entry; - 1119 : const char* name; - 1120 : struct dirent* dd; - 1121 : size_t name_len; - 1122 : - 1123 : /* clear errno to detect erroneous conditions */ - 1124 1041655 : errno = 0; - 1125 1041655 : dd = readdir(d); - 1126 1041655 : if (dd == 0 && errno != 0) { - 1127 : /* LCOV_EXCL_START */ - 1128 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno)); - 1129 : log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub); - 1130 : exit(EXIT_FAILURE); - 1131 : /* LCOV_EXCL_STOP */ - 1132 : } - 1133 1041655 : if (dd == 0) { - 1134 1614 : break; /* finished */ - 1135 : } - 1136 : - 1137 : /* skip "." and ".." files */ - 1138 1040041 : name = dd->d_name; - 1139 1040041 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) - 1140 6456 : continue; - 1141 : - 1142 1036813 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); - 1143 1036813 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); - 1144 : - 1145 : /* check for not supported file names */ - 1146 1036813 : if (name[0] == 0) { - 1147 : /* LCOV_EXCL_START */ - 1148 : log_fatal("Unsupported name '%s' in file '%s'.\n", name, path_next); - 1149 : exit(EXIT_FAILURE); - 1150 : /* LCOV_EXCL_STOP */ - 1151 : } - 1152 : - 1153 : /* exclude hidden files even before calling lstat() */ - 1154 1036813 : if (filter_hidden(state->filter_hidden, dd) != 0) { - 1155 0 : msg_verbose("Excluding hidden '%s'\n", path_next); - 1156 0 : continue; - 1157 : } - 1158 : - 1159 : /* exclude content files even before calling lstat() */ - 1160 1036813 : if (filter_content(&state->contentlist, path_next) != 0) { - 1161 0 : msg_verbose("Excluding content '%s'\n", path_next); - 1162 0 : continue; + 1114 1614 : d = opendir(dir); + 1115 1614 : if (!d) { + 1116 : /* LCOV_EXCL_START */ + 1117 : log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno)); + 1118 : if (level == 0) + 1119 : log_fatal("If this is the disk mount point, remember to create it manually\n"); + 1120 : else + 1121 : log_fatal("If it's a permission problem, you can exclude it in the config file with:\n\texclude /%s\n", sub); + 1122 : exit(EXIT_FAILURE); + 1123 : /* LCOV_EXCL_STOP */ + 1124 : } + 1125 : + 1126 : /* read the full directory */ + 1127 : while (1) { + 1128 : char path_next[PATH_MAX]; + 1129 : char sub_next[PATH_MAX]; + 1130 : struct dirent_sorted* entry; + 1131 : const char* name; + 1132 : struct dirent* dd; + 1133 : size_t name_len; + 1134 : + 1135 : /* clear errno to detect erroneous conditions */ + 1136 1041725 : errno = 0; + 1137 1041725 : dd = readdir(d); + 1138 1041725 : if (dd == 0 && errno != 0) { + 1139 : /* LCOV_EXCL_START */ + 1140 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno)); + 1141 : log_fatal("You can exclude it in the config file with:\n\texclude /%s\n", sub); + 1142 : exit(EXIT_FAILURE); + 1143 : /* LCOV_EXCL_STOP */ + 1144 : } + 1145 1041725 : if (dd == 0) { + 1146 1614 : break; /* finished */ + 1147 : } + 1148 : + 1149 : /* skip "." and ".." files */ + 1150 1040111 : name = dd->d_name; + 1151 1040111 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + 1152 6456 : continue; + 1153 : + 1154 1036883 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 1155 1036883 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); + 1156 : + 1157 : /* check for not supported file names */ + 1158 1036883 : if (name[0] == 0) { + 1159 : /* LCOV_EXCL_START */ + 1160 : log_fatal("Unsupported name '%s' in file '%s'.\n", name, path_next); + 1161 : exit(EXIT_FAILURE); + 1162 : /* LCOV_EXCL_STOP */ 1163 : } 1164 : - 1165 1036813 : name_len = strlen(dd->d_name); - 1166 1036813 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1); - 1167 : - 1168 : /* copy the dir entry */ - 1169 : #if HAVE_STRUCT_DIRENT_D_INO - 1170 1036813 : entry->d_ino = dd->d_ino; - 1171 : #endif - 1172 : #if HAVE_STRUCT_DIRENT_D_TYPE - 1173 1036813 : entry->d_type = dd->d_type; - 1174 : #endif - 1175 : #if HAVE_STRUCT_DIRENT_D_STAT - 1176 : /* convert dirent to lstat result */ - 1177 : dirent_lstat(dd, &entry->d_stat); - 1178 : - 1179 : /* note that at this point the st_mode may be 0 */ - 1180 : #endif - 1181 1036813 : memcpy(entry->d_name, dd->d_name, name_len + 1); - 1182 : - 1183 : /* insert in the list */ - 1184 1036813 : tommy_list_insert_tail(&list, &entry->node, entry); - 1185 1040041 : } - 1186 : - 1187 1614 : if (closedir(d) != 0) { - 1188 : /* LCOV_EXCL_START */ - 1189 : log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno)); - 1190 : exit(EXIT_FAILURE); - 1191 : /* LCOV_EXCL_STOP */ - 1192 : } - 1193 : - 1194 1614 : if (state->opt.force_order == SORT_ALPHA) { - 1195 : /* if requested sort alphabetically */ - 1196 : /* this is mainly done for testing to ensure to always */ - 1197 : /* process in the same way in different platforms */ - 1198 1578 : tommy_list_sort(&list, dd_name_compare); - 1199 : } - 1200 : #if HAVE_STRUCT_DIRENT_D_INO - 1201 36 : else if (!disk->has_volatile_inodes) { - 1202 : /* if inodes are persistent */ - 1203 : /* sort the list of dir entries by inodes */ - 1204 36 : tommy_list_sort(&list, dd_ino_compare); - 1205 : } - 1206 : /* otherwise just keep the insertion order */ - 1207 : #endif - 1208 : - 1209 : /* process the sorted dir entries */ - 1210 1614 : node = list; - 1211 1040041 : while (node != 0) { - 1212 : char path_next[PATH_MAX]; - 1213 : char sub_next[PATH_MAX]; - 1214 : char out[PATH_MAX]; - 1215 1036813 : struct snapraid_filter* reason = 0; - 1216 1036813 : struct dirent_sorted* dd = node->data; - 1217 1036813 : const char* name = dd->d_name; - 1218 : struct stat* st; - 1219 : int type; - 1220 : #if !HAVE_STRUCT_DIRENT_D_STAT - 1221 : struct stat st_buf; - 1222 : #endif - 1223 : - 1224 1036813 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); - 1225 1036813 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); - 1226 : - 1227 : /* start with an unknown type */ - 1228 1036813 : type = -1; - 1229 1036813 : st = 0; - 1230 : - 1231 : /* if dirent has the type, use it */ - 1232 : #if HAVE_STRUCT_DIRENT_D_TYPE - 1233 1036813 : switch (dd->d_type) { - 1234 0 : case DT_UNKNOWN : break; - 1235 1003012 : case DT_REG : type = 0; break; - 1236 32666 : case DT_LNK : type = 1; break; - 1237 1135 : case DT_DIR : type = 2; break; - 1238 0 : default : type = 3; break; - 1239 : } - 1240 : #endif - 1241 : - 1242 : /* if type is still unknown */ - 1243 1036813 : if (type < 0) { - 1244 : /* get the type from stat */ - 1245 0 : st = DSTAT(path_next, dd, &st_buf); - 1246 : - 1247 : #if HAVE_STRUCT_DIRENT_D_STAT - 1248 : /* if the st_mode field is missing, takes care to fill it using normal lstat() */ - 1249 : /* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */ - 1250 : /* because we use a directory reading method that doesn't read info about ReparsePoint. */ - 1251 : /* Note that here we cannot call here lstat_sync(), because we don't know what kind */ - 1252 : /* of file is it, and lstat_sync() doesn't always work */ - 1253 : if (st->st_mode == 0) { - 1254 : if (lstat(path_next, st) != 0) { - 1255 : /* LCOV_EXCL_START */ - 1256 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); - 1257 : exit(EXIT_FAILURE); - 1258 : /* LCOV_EXCL_STOP */ - 1259 : } - 1260 : } - 1261 : #endif - 1262 : - 1263 0 : if (S_ISREG(st->st_mode)) - 1264 0 : type = 0; - 1265 0 : else if (S_ISLNK(st->st_mode)) - 1266 0 : type = 1; - 1267 0 : else if (S_ISDIR(st->st_mode)) - 1268 0 : type = 2; - 1269 : else - 1270 0 : type = 3; - 1271 : } - 1272 : - 1273 1036813 : if (type == 0) { /* REG */ - 1274 1003012 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { - 1275 : - 1276 : /* late stat, if not yet called */ - 1277 1003012 : if (!st) - 1278 1003012 : st = DSTAT(path_next, dd, &st_buf); - 1279 : - 1280 : #if HAVE_LSTAT_SYNC - 1281 : /* if the st_ino field is missing, takes care to fill it using the extended lstat() */ - 1282 : /* this can happen only in Windows */ - 1283 : if (st->st_ino == 0) { - 1284 : if (lstat_sync(path_next, st, 0) != 0) { - 1285 : /* LCOV_EXCL_START */ - 1286 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno)); - 1287 : exit(EXIT_FAILURE); - 1288 : /* LCOV_EXCL_STOP */ - 1289 : } - 1290 : } - 1291 : #endif - 1292 : - 1293 1003012 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET); - 1294 1003012 : processed = 1; - 1295 : } else { - 1296 0 : msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); - 1297 : } - 1298 33801 : } else if (type == 1) { /* LNK */ - 1299 32666 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { - 1300 : char subnew[PATH_MAX]; - 1301 : int ret; - 1302 : - 1303 32666 : ret = readlink(path_next, subnew, sizeof(subnew)); - 1304 32666 : if (ret >= PATH_MAX) { - 1305 : /* LCOV_EXCL_START */ - 1306 : log_fatal("Error in readlink file '%s'. Symlink too long.\n", path_next); - 1307 : exit(EXIT_FAILURE); - 1308 : /* LCOV_EXCL_STOP */ - 1309 : } - 1310 32666 : if (ret < 0) { - 1311 : /* LCOV_EXCL_START */ - 1312 : log_fatal("Error in readlink file '%s'. %s.\n", path_next, strerror(errno)); - 1313 : exit(EXIT_FAILURE); - 1314 : /* LCOV_EXCL_STOP */ - 1315 : } - 1316 : - 1317 : /* readlink doesn't put the final 0 */ - 1318 32666 : subnew[ret] = 0; - 1319 : - 1320 : /* process as a symbolic link */ - 1321 32666 : scan_link(scan, is_diff, sub_next, subnew, FILE_IS_SYMLINK); - 1322 32666 : processed = 1; - 1323 : } else { - 1324 0 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); - 1325 : } - 1326 1135 : } else if (type == 2) { /* DIR */ - 1327 1135 : if (filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) { - 1328 : #ifndef _WIN32 - 1329 : /* late stat, if not yet called */ - 1330 1135 : if (!st) - 1331 1135 : st = DSTAT(path_next, dd, &st_buf); - 1332 : - 1333 : /* in Unix don't follow mount points in different devices */ - 1334 : /* in Windows we are already skipping them reporting them as special files */ - 1335 1135 : if ((uint64_t)st->st_dev != disk->device) { - 1336 0 : log_fatal("WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next); - 1337 : } else - 1338 : #endif - 1339 : { - 1340 : char sub_dir[PATH_MAX]; - 1341 : - 1342 : /* recurse */ - 1343 1135 : pathslash(path_next, sizeof(path_next)); - 1344 1135 : pathcpy(sub_dir, sizeof(sub_dir), sub_next); - 1345 1135 : pathslash(sub_dir, sizeof(sub_dir)); - 1346 1135 : if (scan_dir(scan, level + 1, is_diff, path_next, sub_dir) == 0) { - 1347 : /* scan the directory as empty dir */ - 1348 227 : scan_emptydir(scan, sub_next); - 1349 : } - 1350 : /* or we processed something internally, or we have added the empty dir */ - 1351 1135 : processed = 1; - 1352 : } - 1353 : } else { - 1354 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); - 1355 : } - 1356 : } else { - 1357 0 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { - 1358 : /* late stat, if not yet called */ - 1359 0 : if (!st) - 1360 0 : st = DSTAT(path_next, dd, &st_buf); - 1361 : - 1362 0 : log_fatal("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next); - 1363 : } else { - 1364 0 : msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); - 1365 : } - 1366 : } - 1367 : - 1368 : /* next entry */ - 1369 1036813 : node = node->next; - 1370 : - 1371 : /* free the present one */ - 1372 1036813 : free(dd); - 1373 : } - 1374 : - 1375 1614 : return processed; - 1376 : } - 1377 : - 1378 80 : static int state_diffscan(struct snapraid_state* state, int is_diff) - 1379 : { - 1380 : tommy_node* i; - 1381 : tommy_node* j; - 1382 : tommy_list scanlist; - 1383 : int done; - 1384 : fptr* msg; - 1385 : struct snapraid_scan total; - 1386 : int no_difference; - 1387 : - 1388 80 : tommy_list_init(&scanlist); + 1165 : /* exclude hidden files even before calling lstat() */ + 1166 1036883 : if (filter_hidden(state->filter_hidden, dd) != 0) { + 1167 0 : msg_verbose("Excluding hidden '%s'\n", path_next); + 1168 0 : continue; + 1169 : } + 1170 : + 1171 : /* exclude content files even before calling lstat() */ + 1172 1036883 : if (filter_content(&state->contentlist, path_next) != 0) { + 1173 0 : msg_verbose("Excluding content '%s'\n", path_next); + 1174 0 : continue; + 1175 : } + 1176 : + 1177 1036883 : name_len = strlen(dd->d_name); + 1178 1036883 : entry = malloc_nofail(sizeof(struct dirent_sorted) + name_len + 1); + 1179 : + 1180 : /* copy the dir entry */ + 1181 : #if HAVE_STRUCT_DIRENT_D_INO + 1182 1036883 : entry->d_ino = dd->d_ino; + 1183 : #endif + 1184 : #if HAVE_STRUCT_DIRENT_D_TYPE + 1185 1036883 : entry->d_type = dd->d_type; + 1186 : #endif + 1187 : #if HAVE_STRUCT_DIRENT_D_STAT + 1188 : /* convert dirent to lstat result */ + 1189 : dirent_lstat(dd, &entry->d_stat); + 1190 : + 1191 : /* note that at this point the st_mode may be 0 */ + 1192 : #endif + 1193 1036883 : memcpy(entry->d_name, dd->d_name, name_len + 1); + 1194 : + 1195 : /* insert in the list */ + 1196 1036883 : tommy_list_insert_tail(&list, &entry->node, entry); + 1197 1040111 : } + 1198 : + 1199 1614 : if (closedir(d) != 0) { + 1200 : /* LCOV_EXCL_START */ + 1201 : log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno)); + 1202 : exit(EXIT_FAILURE); + 1203 : /* LCOV_EXCL_STOP */ + 1204 : } + 1205 : + 1206 1614 : if (state->opt.force_order == SORT_ALPHA) { + 1207 : /* if requested sort alphabetically */ + 1208 : /* this is mainly done for testing to ensure to always */ + 1209 : /* process in the same way in different platforms */ + 1210 1578 : tommy_list_sort(&list, dd_name_compare); + 1211 : } + 1212 : #if HAVE_STRUCT_DIRENT_D_INO + 1213 36 : else if (!disk->has_volatile_inodes) { + 1214 : /* if inodes are persistent */ + 1215 : /* sort the list of dir entries by inodes */ + 1216 36 : tommy_list_sort(&list, dd_ino_compare); + 1217 : } + 1218 : /* otherwise just keep the insertion order */ + 1219 : #endif + 1220 : + 1221 : /* process the sorted dir entries */ + 1222 1614 : node = list; + 1223 1040111 : while (node != 0) { + 1224 : char path_next[PATH_MAX]; + 1225 : char sub_next[PATH_MAX]; + 1226 : char out[PATH_MAX]; + 1227 1036883 : struct snapraid_filter* reason = 0; + 1228 1036883 : struct dirent_sorted* dd = node->data; + 1229 1036883 : const char* name = dd->d_name; + 1230 : struct stat* st; + 1231 : int type; + 1232 : #if !HAVE_STRUCT_DIRENT_D_STAT + 1233 : struct stat st_buf; + 1234 : #endif + 1235 : + 1236 1036883 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 1237 1036883 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); + 1238 : + 1239 : /* start with an unknown type */ + 1240 1036883 : type = -1; + 1241 1036883 : st = 0; + 1242 : + 1243 : /* if dirent has the type, use it */ + 1244 : #if HAVE_STRUCT_DIRENT_D_TYPE + 1245 1036883 : switch (dd->d_type) { + 1246 0 : case DT_UNKNOWN : break; + 1247 1003082 : case DT_REG : type = 0; break; + 1248 32666 : case DT_LNK : type = 1; break; + 1249 1135 : case DT_DIR : type = 2; break; + 1250 0 : default : type = 3; break; + 1251 : } + 1252 : #endif + 1253 : + 1254 : /* if type is still unknown */ + 1255 1036883 : if (type < 0) { + 1256 : /* get the type from stat */ + 1257 0 : st = DSTAT(path_next, dd, &st_buf); + 1258 : + 1259 : #if HAVE_STRUCT_DIRENT_D_STAT + 1260 : /* if the st_mode field is missing, takes care to fill it using normal lstat() */ + 1261 : /* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */ + 1262 : /* because we use a directory reading method that doesn't read info about ReparsePoint. */ + 1263 : /* Note that here we cannot call here lstat_sync(), because we don't know what kind */ + 1264 : /* of file is it, and lstat_sync() doesn't always work */ + 1265 : if (st->st_mode == 0) { + 1266 : if (lstat(path_next, st) != 0) { + 1267 : /* LCOV_EXCL_START */ + 1268 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); + 1269 : exit(EXIT_FAILURE); + 1270 : /* LCOV_EXCL_STOP */ + 1271 : } + 1272 : } + 1273 : #endif + 1274 : + 1275 0 : if (S_ISREG(st->st_mode)) + 1276 0 : type = 0; + 1277 0 : else if (S_ISLNK(st->st_mode)) + 1278 0 : type = 1; + 1279 0 : else if (S_ISDIR(st->st_mode)) + 1280 0 : type = 2; + 1281 : else + 1282 0 : type = 3; + 1283 : } + 1284 : + 1285 1036883 : if (type == 0) { /* REG */ + 1286 1003082 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 1287 : + 1288 : /* late stat, if not yet called */ + 1289 1003082 : if (!st) + 1290 1003082 : st = DSTAT(path_next, dd, &st_buf); + 1291 : + 1292 : #if HAVE_LSTAT_SYNC + 1293 : /* if the st_ino field is missing, takes care to fill it using the extended lstat() */ + 1294 : /* this can happen only in Windows */ + 1295 : if (st->st_ino == 0) { + 1296 : if (lstat_sync(path_next, st, 0) != 0) { + 1297 : /* LCOV_EXCL_START */ + 1298 : log_fatal("Error in stat file '%s'. %s.\n", path_next, strerror(errno)); + 1299 : exit(EXIT_FAILURE); + 1300 : /* LCOV_EXCL_STOP */ + 1301 : } + 1302 : } + 1303 : #endif + 1304 : + 1305 1003082 : scan_file(scan, is_diff, sub_next, st, FILEPHY_UNREAD_OFFSET); + 1306 1003082 : processed = 1; + 1307 : } else { + 1308 0 : msg_verbose("Excluding file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); + 1309 : } + 1310 33801 : } else if (type == 1) { /* LNK */ + 1311 32666 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 1312 : char subnew[PATH_MAX]; + 1313 : int ret; + 1314 : + 1315 32666 : ret = readlink(path_next, subnew, sizeof(subnew)); + 1316 32666 : if (ret >= PATH_MAX) { + 1317 : /* LCOV_EXCL_START */ + 1318 : log_fatal("Error in readlink file '%s'. Symlink too long.\n", path_next); + 1319 : exit(EXIT_FAILURE); + 1320 : /* LCOV_EXCL_STOP */ + 1321 : } + 1322 32666 : if (ret < 0) { + 1323 : /* LCOV_EXCL_START */ + 1324 : log_fatal("Error in readlink file '%s'. %s.\n", path_next, strerror(errno)); + 1325 : exit(EXIT_FAILURE); + 1326 : /* LCOV_EXCL_STOP */ + 1327 : } + 1328 : + 1329 : /* readlink doesn't put the final 0 */ + 1330 32666 : subnew[ret] = 0; + 1331 : + 1332 : /* process as a symbolic link */ + 1333 32666 : scan_link(scan, is_diff, sub_next, subnew, FILE_IS_SYMLINK); + 1334 32666 : processed = 1; + 1335 : } else { + 1336 0 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); + 1337 : } + 1338 1135 : } else if (type == 2) { /* DIR */ + 1339 1135 : if (filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 1340 : #ifndef _WIN32 + 1341 : /* late stat, if not yet called */ + 1342 1135 : if (!st) + 1343 1135 : st = DSTAT(path_next, dd, &st_buf); + 1344 : + 1345 : /* in Unix don't follow mount points in different devices */ + 1346 : /* in Windows we are already skipping them reporting them as special files */ + 1347 1135 : if ((uint64_t)st->st_dev != disk->device) { + 1348 0 : log_fatal("WARNING! Ignoring mount point '%s' because it appears to be in a different device\n", path_next); + 1349 : } else + 1350 : #endif + 1351 : { + 1352 : char sub_dir[PATH_MAX]; + 1353 : + 1354 : /* recurse */ + 1355 1135 : pathslash(path_next, sizeof(path_next)); + 1356 1135 : pathcpy(sub_dir, sizeof(sub_dir), sub_next); + 1357 1135 : pathslash(sub_dir, sizeof(sub_dir)); + 1358 1135 : if (scan_dir(scan, level + 1, is_diff, path_next, sub_dir) == 0) { + 1359 : /* scan the directory as empty dir */ + 1360 227 : scan_emptydir(scan, sub_next); + 1361 : } + 1362 : /* or we processed something internally, or we have added the empty dir */ + 1363 1135 : processed = 1; + 1364 : } + 1365 : } else { + 1366 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); + 1367 : } + 1368 : } else { + 1369 0 : if (filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 1370 : /* late stat, if not yet called */ + 1371 0 : if (!st) + 1372 0 : st = DSTAT(path_next, dd, &st_buf); + 1373 : + 1374 0 : log_fatal("WARNING! Ignoring special '%s' file '%s'\n", stat_desc(st), path_next); + 1375 : } else { + 1376 0 : msg_verbose("Excluding special file '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); + 1377 : } + 1378 : } + 1379 : + 1380 : /* next entry */ + 1381 1036883 : node = node->next; + 1382 : + 1383 : /* free the present one */ + 1384 1036883 : free(dd); + 1385 : } + 1386 : + 1387 1614 : return processed; + 1388 : } 1389 : - 1390 80 : if (is_diff) - 1391 7 : msg_progress("Comparing...\n"); - 1392 : - 1393 : /* first scan all the directory and find new and deleted files */ - 1394 559 : for (i = state->disklist; i != 0; i = i->next) { - 1395 479 : struct snapraid_disk* disk = i->data; - 1396 : struct snapraid_scan* scan; - 1397 : tommy_node* node; - 1398 : int ret; - 1399 : int has_persistent_inode; - 1400 : - 1401 479 : scan = malloc_nofail(sizeof(struct snapraid_scan)); - 1402 479 : scan->state = state; - 1403 479 : scan->disk = disk; - 1404 479 : scan->count_equal = 0; - 1405 479 : scan->count_move = 0; - 1406 479 : scan->count_copy = 0; - 1407 479 : scan->count_restore = 0; - 1408 479 : scan->count_change = 0; - 1409 479 : scan->count_remove = 0; - 1410 479 : scan->count_insert = 0; - 1411 479 : tommy_list_init(&scan->file_insert_list); - 1412 479 : tommy_list_init(&scan->link_insert_list); - 1413 479 : tommy_list_init(&scan->dir_insert_list); - 1414 : - 1415 479 : tommy_list_insert_tail(&scanlist, &scan->node, scan); - 1416 : - 1417 479 : if (!is_diff) - 1418 437 : msg_progress("Scanning disk %s...\n", disk->name); - 1419 : - 1420 : /* check if the disk supports persistent inodes */ - 1421 479 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0); - 1422 479 : if (ret < 0) { - 1423 : /* LCOV_EXCL_START */ - 1424 : log_fatal("Error accessing disk '%s' to get filesystem info. %s.\n", disk->dir, strerror(errno)); - 1425 : exit(EXIT_FAILURE); - 1426 : /* LCOV_EXCL_STOP */ - 1427 : } - 1428 479 : if (!has_persistent_inode) { - 1429 0 : disk->has_volatile_inodes = 1; - 1430 : } + 1390 80 : static int state_diffscan(struct snapraid_state* state, int is_diff) + 1391 : { + 1392 : tommy_node* i; + 1393 : tommy_node* j; + 1394 : tommy_list scanlist; + 1395 : int done; + 1396 : fptr* msg; + 1397 : struct snapraid_scan total; + 1398 : int no_difference; + 1399 : + 1400 80 : tommy_list_init(&scanlist); + 1401 : + 1402 80 : if (is_diff) + 1403 7 : msg_progress("Comparing...\n"); + 1404 : + 1405 : /* first scan all the directory and find new and deleted files */ + 1406 559 : for (i = state->disklist; i != 0; i = i->next) { + 1407 479 : struct snapraid_disk* disk = i->data; + 1408 : struct snapraid_scan* scan; + 1409 : tommy_node* node; + 1410 : int ret; + 1411 : int has_persistent_inode; + 1412 : + 1413 479 : scan = malloc_nofail(sizeof(struct snapraid_scan)); + 1414 479 : scan->state = state; + 1415 479 : scan->disk = disk; + 1416 479 : scan->count_equal = 0; + 1417 479 : scan->count_move = 0; + 1418 479 : scan->count_copy = 0; + 1419 479 : scan->count_restore = 0; + 1420 479 : scan->count_change = 0; + 1421 479 : scan->count_remove = 0; + 1422 479 : scan->count_insert = 0; + 1423 479 : tommy_list_init(&scan->file_insert_list); + 1424 479 : tommy_list_init(&scan->link_insert_list); + 1425 479 : tommy_list_init(&scan->dir_insert_list); + 1426 : + 1427 479 : tommy_list_insert_tail(&scanlist, &scan->node, scan); + 1428 : + 1429 479 : if (!is_diff) + 1430 437 : msg_progress("Scanning disk %s...\n", disk->name); 1431 : - 1432 : /* if inodes or UUID are not persistent/changed/unsupported */ - 1433 479 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) { - 1434 : /* remove all the inodes from the inode collection */ - 1435 : /* if they are not persistent, all of them could be changed now */ - 1436 : /* and we don't want to find false matching ones */ - 1437 : /* see scan_file() for more details */ - 1438 75 : node = disk->filelist; - 1439 150 : while (node) { - 1440 0 : struct snapraid_file* file = node->data; - 1441 : - 1442 0 : node = node->next; + 1432 : /* check if the disk supports persistent inodes */ + 1433 479 : ret = fsinfo(disk->dir, &has_persistent_inode, 0, 0); + 1434 479 : if (ret < 0) { + 1435 : /* LCOV_EXCL_START */ + 1436 : log_fatal("Error accessing disk '%s' to get filesystem info. %s.\n", disk->dir, strerror(errno)); + 1437 : exit(EXIT_FAILURE); + 1438 : /* LCOV_EXCL_STOP */ + 1439 : } + 1440 479 : if (!has_persistent_inode) { + 1441 0 : disk->has_volatile_inodes = 1; + 1442 : } 1443 : - 1444 : /* remove from the inode set */ - 1445 0 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); - 1446 : - 1447 : /* clear the inode */ - 1448 0 : file->inode = 0; - 1449 : - 1450 : /* mark as missing inode */ - 1451 0 : file_flag_set(file, FILE_IS_WITHOUT_INODE); - 1452 : } - 1453 : } - 1454 : - 1455 479 : scan_dir(scan, 0, is_diff, disk->dir, ""); - 1456 : } - 1457 : - 1458 : /* we split the search in two phases because to detect files */ - 1459 : /* moved from one disk to another we have to start deletion */ - 1460 : /* only when all disks have all the new files found */ + 1444 : /* if inodes or UUID are not persistent/changed/unsupported */ + 1445 479 : if (disk->has_volatile_inodes || disk->has_different_uuid || disk->has_unsupported_uuid) { + 1446 : /* remove all the inodes from the inode collection */ + 1447 : /* if they are not persistent, all of them could be changed now */ + 1448 : /* and we don't want to find false matching ones */ + 1449 : /* see scan_file() for more details */ + 1450 75 : node = disk->filelist; + 1451 150 : while (node) { + 1452 0 : struct snapraid_file* file = node->data; + 1453 : + 1454 0 : node = node->next; + 1455 : + 1456 : /* remove from the inode set */ + 1457 0 : tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + 1458 : + 1459 : /* clear the inode */ + 1460 0 : file->inode = 0; 1461 : - 1462 : /* now process all the new and deleted files */ - 1463 559 : for (i = scanlist; i != 0; i = i->next) { - 1464 479 : struct snapraid_scan* scan = i->data; - 1465 479 : struct snapraid_disk* disk = scan->disk; - 1466 : tommy_node* node; - 1467 : unsigned phy_count; - 1468 : unsigned phy_dup; - 1469 : uint64_t phy_last; - 1470 : struct snapraid_file* phy_file_last; - 1471 : - 1472 : /* check for removed files */ - 1473 479 : node = disk->filelist; - 1474 932507 : while (node) { - 1475 931549 : struct snapraid_file* file = node->data; - 1476 : - 1477 : /* next node */ - 1478 931549 : node = node->next; - 1479 : - 1480 : /* remove if not present */ - 1481 931549 : if (!file_flag_has(file, FILE_IS_PRESENT)) { - 1482 29638 : ++scan->count_remove; + 1462 : /* mark as missing inode */ + 1463 0 : file_flag_set(file, FILE_IS_WITHOUT_INODE); + 1464 : } + 1465 : } + 1466 : + 1467 479 : scan_dir(scan, 0, is_diff, disk->dir, ""); + 1468 : } + 1469 : + 1470 : /* we split the search in two phases because to detect files */ + 1471 : /* moved from one disk to another we have to start deletion */ + 1472 : /* only when all disks have all the new files found */ + 1473 : + 1474 : /* now process all the new and deleted files */ + 1475 559 : for (i = scanlist; i != 0; i = i->next) { + 1476 479 : struct snapraid_scan* scan = i->data; + 1477 479 : struct snapraid_disk* disk = scan->disk; + 1478 : tommy_node* node; + 1479 : unsigned phy_count; + 1480 : unsigned phy_dup; + 1481 : uint64_t phy_last; + 1482 : struct snapraid_file* phy_file_last; 1483 : - 1484 29638 : log_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub)); - 1485 29638 : if (is_diff) { - 1486 97 : printf("remove %s%s\n", disk->dir, file->sub); - 1487 : } + 1484 : /* check for removed files */ + 1485 479 : node = disk->filelist; + 1486 932532 : while (node) { + 1487 931574 : struct snapraid_file* file = node->data; 1488 : - 1489 29638 : scan_file_remove(scan, file); - 1490 : } - 1491 : } - 1492 : - 1493 : /* check for removed links */ - 1494 479 : node = disk->linklist; - 1495 32294 : while (node) { - 1496 31336 : struct snapraid_link* slink = node->data; - 1497 : - 1498 : /* next node */ - 1499 31336 : node = node->next; + 1489 : /* next node */ + 1490 931574 : node = node->next; + 1491 : + 1492 : /* remove if not present */ + 1493 931574 : if (!file_flag_has(file, FILE_IS_PRESENT)) { + 1494 29638 : ++scan->count_remove; + 1495 : + 1496 29638 : log_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub)); + 1497 29638 : if (is_diff) { + 1498 97 : printf("remove %s%s\n", disk->dir, file->sub); + 1499 : } 1500 : - 1501 : /* remove if not present */ - 1502 31336 : if (!link_flag_has(slink, FILE_IS_PRESENT)) { - 1503 956 : ++scan->count_remove; + 1501 29638 : scan_file_remove(scan, file); + 1502 : } + 1503 : } 1504 : - 1505 956 : log_tag("scan:remove:%s:%s\n", disk->name, esc(slink->sub)); - 1506 956 : if (is_diff) { - 1507 10 : printf("remove %s%s\n", disk->dir, slink->sub); - 1508 : } + 1505 : /* check for removed links */ + 1506 479 : node = disk->linklist; + 1507 32294 : while (node) { + 1508 31336 : struct snapraid_link* slink = node->data; 1509 : - 1510 956 : scan_link_remove(scan, slink); - 1511 : } - 1512 : } - 1513 : - 1514 : /* check for removed dirs */ - 1515 479 : node = disk->dirlist; - 1516 1177 : while (node) { - 1517 219 : struct snapraid_dir* dir = node->data; - 1518 : - 1519 : /* next node */ - 1520 219 : node = node->next; + 1510 : /* next node */ + 1511 31336 : node = node->next; + 1512 : + 1513 : /* remove if not present */ + 1514 31336 : if (!link_flag_has(slink, FILE_IS_PRESENT)) { + 1515 956 : ++scan->count_remove; + 1516 : + 1517 956 : log_tag("scan:remove:%s:%s\n", disk->name, esc(slink->sub)); + 1518 956 : if (is_diff) { + 1519 10 : printf("remove %s%s\n", disk->dir, slink->sub); + 1520 : } 1521 : - 1522 : /* remove if not present */ - 1523 219 : if (!dir_flag_has(dir, FILE_IS_PRESENT)) { - 1524 2 : scan_emptydir_remove(scan, dir); - 1525 : } - 1526 : } - 1527 : - 1528 : /* sort the files before inserting them */ - 1529 : /* we use a stable sort to ensure that if the reported physical offset/inode */ - 1530 : /* are always 0, we keep at least the directory order */ - 1531 479 : switch (state->opt.force_order) { - 1532 : case SORT_PHYSICAL : - 1533 12 : tommy_list_sort(&scan->file_insert_list, file_physical_compare); - 1534 12 : break; - 1535 : case SORT_INODE : - 1536 0 : tommy_list_sort(&scan->file_insert_list, file_inode_compare); - 1537 0 : break; - 1538 : case SORT_ALPHA : - 1539 467 : tommy_list_sort(&scan->file_insert_list, file_path_compare); - 1540 467 : break; - 1541 : case SORT_DIR : - 1542 : /* already in order */ - 1543 0 : break; - 1544 : } - 1545 : - 1546 : /* insert all the new files, we insert them only after the deletion */ - 1547 : /* to reuse the just freed space */ - 1548 : /* also check if the physical offset reported are fakes or not */ - 1549 479 : node = scan->file_insert_list; - 1550 479 : phy_count = 0; - 1551 479 : phy_dup = 0; - 1552 479 : phy_last = FILEPHY_UNREAD_OFFSET; - 1553 479 : phy_file_last = 0; - 1554 101888 : while (node) { - 1555 100930 : struct snapraid_file* file = node->data; - 1556 : - 1557 : /* if the file is not empty, count duplicate physical offsets */ - 1558 100930 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) { - 1559 11418 : if (phy_file_last != 0 && file->physical == phy_last - 1560 : /* files without offset are expected to have duplicates */ - 1561 0 : && phy_last != FILEPHY_WITHOUT_OFFSET - 1562 : ) { - 1563 : /* if verbose, print the list of duplicates real offsets */ - 1564 : /* other cases are for offsets not supported, so we don't need to report them file by file */ - 1565 0 : if (phy_last >= FILEPHY_REAL_OFFSET) { - 1566 0 : log_fatal("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last); - 1567 : } - 1568 0 : ++phy_dup; - 1569 : } - 1570 11418 : phy_file_last = file; - 1571 11418 : phy_last = file->physical; - 1572 11418 : ++phy_count; - 1573 : } - 1574 : - 1575 : /* next node */ - 1576 100930 : node = node->next; - 1577 : - 1578 : /* insert in the parity */ - 1579 100930 : scan_file_allocate(scan, file); - 1580 : } - 1581 : - 1582 : /* mark the disk without reliable physical offset if it has duplicates */ - 1583 : /* here it should never happen because we already sorted out hardlinks */ - 1584 479 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) { - 1585 0 : disk->has_unreliable_physical = 1; - 1586 : } - 1587 : - 1588 : /* insert all the new links */ - 1589 479 : node = scan->link_insert_list; - 1590 3415 : while (node) { - 1591 2457 : struct snapraid_link* slink = node->data; - 1592 : - 1593 : /* next node */ - 1594 2457 : node = node->next; - 1595 : - 1596 : /* insert it */ - 1597 2457 : scan_link_insert(scan, slink); + 1522 956 : scan_link_remove(scan, slink); + 1523 : } + 1524 : } + 1525 : + 1526 : /* check for removed dirs */ + 1527 479 : node = disk->dirlist; + 1528 1177 : while (node) { + 1529 219 : struct snapraid_dir* dir = node->data; + 1530 : + 1531 : /* next node */ + 1532 219 : node = node->next; + 1533 : + 1534 : /* remove if not present */ + 1535 219 : if (!dir_flag_has(dir, FILE_IS_PRESENT)) { + 1536 2 : scan_emptydir_remove(scan, dir); + 1537 : } + 1538 : } + 1539 : + 1540 : /* sort the files before inserting them */ + 1541 : /* we use a stable sort to ensure that if the reported physical offset/inode */ + 1542 : /* are always 0, we keep at least the directory order */ + 1543 479 : switch (state->opt.force_order) { + 1544 : case SORT_PHYSICAL : + 1545 12 : tommy_list_sort(&scan->file_insert_list, file_physical_compare); + 1546 12 : break; + 1547 : case SORT_INODE : + 1548 0 : tommy_list_sort(&scan->file_insert_list, file_inode_compare); + 1549 0 : break; + 1550 : case SORT_ALPHA : + 1551 467 : tommy_list_sort(&scan->file_insert_list, file_path_compare); + 1552 467 : break; + 1553 : case SORT_DIR : + 1554 : /* already in order */ + 1555 0 : break; + 1556 : } + 1557 : + 1558 : /* insert all the new files, we insert them only after the deletion */ + 1559 : /* to reuse the just freed space */ + 1560 : /* also check if the physical offset reported are fakes or not */ + 1561 479 : node = scan->file_insert_list; + 1562 479 : phy_count = 0; + 1563 479 : phy_dup = 0; + 1564 479 : phy_last = FILEPHY_UNREAD_OFFSET; + 1565 479 : phy_file_last = 0; + 1566 101933 : while (node) { + 1567 100975 : struct snapraid_file* file = node->data; + 1568 : + 1569 : /* if the file is not empty, count duplicate physical offsets */ + 1570 100975 : if (state->opt.force_order == SORT_PHYSICAL && file->size != 0) { + 1571 11418 : if (phy_file_last != 0 && file->physical == phy_last + 1572 : /* files without offset are expected to have duplicates */ + 1573 0 : && phy_last != FILEPHY_WITHOUT_OFFSET + 1574 : ) { + 1575 : /* if verbose, print the list of duplicates real offsets */ + 1576 : /* other cases are for offsets not supported, so we don't need to report them file by file */ + 1577 0 : if (phy_last >= FILEPHY_REAL_OFFSET) { + 1578 0 : log_fatal("WARNING! Files '%s%s' and '%s%s' have the same physical offset %" PRId64 ".\n", disk->dir, phy_file_last->sub, disk->dir, file->sub, phy_last); + 1579 : } + 1580 0 : ++phy_dup; + 1581 : } + 1582 11418 : phy_file_last = file; + 1583 11418 : phy_last = file->physical; + 1584 11418 : ++phy_count; + 1585 : } + 1586 : + 1587 : /* next node */ + 1588 100975 : node = node->next; + 1589 : + 1590 : /* insert in the parity */ + 1591 100975 : scan_file_allocate(scan, file); + 1592 : } + 1593 : + 1594 : /* mark the disk without reliable physical offset if it has duplicates */ + 1595 : /* here it should never happen because we already sorted out hardlinks */ + 1596 479 : if (state->opt.force_order == SORT_PHYSICAL && phy_dup > 0) { + 1597 0 : disk->has_unreliable_physical = 1; 1598 : } 1599 : - 1600 : /* insert all the new dirs */ - 1601 479 : node = scan->dir_insert_list; - 1602 968 : while (node) { - 1603 10 : struct snapraid_dir* dir = node->data; + 1600 : /* insert all the new links */ + 1601 479 : node = scan->link_insert_list; + 1602 3415 : while (node) { + 1603 2457 : struct snapraid_link* slink = node->data; 1604 : 1605 : /* next node */ - 1606 10 : node = node->next; + 1606 2457 : node = node->next; 1607 : 1608 : /* insert it */ - 1609 10 : scan_emptydir_insert(scan, dir); + 1609 2457 : scan_link_insert(scan, slink); 1610 : } - 1611 : } - 1612 : - 1613 : /* check for disks where all the previously existing files where removed */ - 1614 80 : if (!state->opt.force_empty) { - 1615 75 : int all_missing = 0; - 1616 75 : int all_rewritten = 0; - 1617 75 : done = 0; - 1618 524 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) { - 1619 449 : struct snapraid_disk* disk = i->data; - 1620 449 : struct snapraid_scan* scan = j->data; - 1621 : - 1622 449 : if (scan->count_equal == 0 - 1623 60 : && scan->count_move == 0 - 1624 60 : && scan->count_restore == 0 - 1625 60 : && (scan->count_remove != 0 || scan->count_change != 0) - 1626 : ) { - 1627 1 : if (!done) { - 1628 1 : done = 1; - 1629 1 : log_fatal("WARNING! All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir); - 1630 : } else { - 1631 0 : log_fatal(", disk '%s' at dir '%s'", disk->name, disk->dir); - 1632 : } + 1611 : + 1612 : /* insert all the new dirs */ + 1613 479 : node = scan->dir_insert_list; + 1614 968 : while (node) { + 1615 10 : struct snapraid_dir* dir = node->data; + 1616 : + 1617 : /* next node */ + 1618 10 : node = node->next; + 1619 : + 1620 : /* insert it */ + 1621 10 : scan_emptydir_insert(scan, dir); + 1622 : } + 1623 : } + 1624 : + 1625 : /* check for disks where all the previously existing files where removed */ + 1626 80 : if (!state->opt.force_empty) { + 1627 75 : int all_missing = 0; + 1628 75 : int all_rewritten = 0; + 1629 75 : done = 0; + 1630 524 : for (i = state->disklist, j = scanlist; i != 0; i = i->next, j = j->next) { + 1631 449 : struct snapraid_disk* disk = i->data; + 1632 449 : struct snapraid_scan* scan = j->data; 1633 : - 1634 : /* detect the special condition of all files missing */ - 1635 1 : if (scan->count_change == 0) - 1636 1 : all_missing = 1; - 1637 : - 1638 : /* detect the special condition of all files rewritten */ - 1639 1 : if (scan->count_remove == 0) - 1640 0 : all_rewritten = 1; - 1641 : } - 1642 : } - 1643 75 : if (done) { - 1644 1 : log_fatal("\nare now missing or rewritten!\n"); - 1645 1 : if (all_rewritten) { - 1646 0 : log_fatal("This could happen when restoring a disk with a backup\n"); - 1647 0 : log_fatal("program that is not setting correctly the timestamps.\n"); - 1648 : } - 1649 1 : if (all_missing) { - 1650 1 : log_fatal("This could happen when some disks are not mounted\n"); - 1651 1 : log_fatal("in the expected directory.\n"); - 1652 : } - 1653 1 : if (!is_diff) { - 1654 1 : log_fatal("If you want to '%s' anyway, use 'snapraid --force-empty %s'.", state->command, state->command); - 1655 1 : exit(EXIT_FAILURE); - 1656 : } - 1657 : } - 1658 : } - 1659 : - 1660 : /* check for disks without the physical offset support */ - 1661 79 : if (state->opt.force_order == SORT_PHYSICAL) { - 1662 2 : done = 0; - 1663 14 : for (i = state->disklist; i != 0; i = i->next) { - 1664 12 : struct snapraid_disk* disk = i->data; - 1665 : - 1666 12 : if (disk->has_unreliable_physical) { - 1667 0 : if (!done) { - 1668 0 : done = 1; - 1669 0 : log_fatal("WARNING! Physical offsets not supported for disk '%s'", disk->name); - 1670 : } else { - 1671 0 : log_fatal(", '%s'", disk->name); - 1672 : } - 1673 : } - 1674 : } - 1675 2 : if (done) { - 1676 0 : log_fatal(". Files order won't be optimal.\n"); - 1677 : } - 1678 : } - 1679 : - 1680 : /* check for disks without persistent inodes */ - 1681 79 : done = 0; - 1682 552 : for (i = state->disklist; i != 0; i = i->next) { - 1683 473 : struct snapraid_disk* disk = i->data; - 1684 : - 1685 473 : if (disk->has_volatile_inodes) { - 1686 0 : if (!done) { - 1687 0 : done = 1; - 1688 0 : log_fatal("WARNING! Inodes are not persistent for disks: '%s'", disk->name); - 1689 : } else { - 1690 0 : log_fatal(", '%s'", disk->name); - 1691 : } - 1692 : } - 1693 : } - 1694 79 : if (done) { - 1695 0 : log_fatal(". Move operations won't be optimal.\n"); - 1696 : } - 1697 : - 1698 : /* check for disks with changed UUID */ - 1699 79 : done = 0; - 1700 552 : for (i = state->disklist; i != 0; i = i->next) { - 1701 473 : struct snapraid_disk* disk = i->data; - 1702 : - 1703 : /* don't print the message if the UUID changed because before */ - 1704 : /* it was no set. */ - 1705 : /* this is the normal condition for an empty disk because it */ - 1706 : /* isn't stored */ - 1707 473 : if (disk->has_different_uuid && !disk->had_empty_uuid) { - 1708 0 : if (!done) { - 1709 0 : done = 1; - 1710 0 : log_fatal("WARNING! UUID is changed for disks: '%s'", disk->name); - 1711 : } else { - 1712 0 : log_fatal(", '%s'", disk->name); - 1713 : } - 1714 : } - 1715 : } - 1716 79 : if (done) { - 1717 0 : log_fatal(". Move operations won't be optimal.\n"); - 1718 : } - 1719 : - 1720 : /* check for disks with unsupported UUID */ - 1721 79 : done = 0; - 1722 552 : for (i = state->disklist; i != 0; i = i->next) { - 1723 473 : struct snapraid_disk* disk = i->data; - 1724 : - 1725 473 : if (disk->has_unsupported_uuid) { - 1726 0 : if (!done) { - 1727 0 : done = 1; - 1728 0 : log_fatal("WARNING! UUID is unsupported for disks: '%s'", disk->name); - 1729 : } else { - 1730 0 : log_fatal(", '%s'", disk->name); - 1731 : } - 1732 : } - 1733 : } - 1734 79 : if (done) { - 1735 0 : log_fatal(". Move operations won't be optimal.\n"); - 1736 : } - 1737 : - 1738 79 : total.count_equal = 0; - 1739 79 : total.count_move = 0; - 1740 79 : total.count_copy = 0; - 1741 79 : total.count_restore = 0; - 1742 79 : total.count_change = 0; - 1743 79 : total.count_remove = 0; - 1744 79 : total.count_insert = 0; - 1745 : - 1746 552 : for (i = scanlist; i != 0; i = i->next) { - 1747 473 : struct snapraid_scan* scan = i->data; - 1748 473 : total.count_equal += scan->count_equal; - 1749 473 : total.count_move += scan->count_move; - 1750 473 : total.count_copy += scan->count_copy; - 1751 473 : total.count_restore += scan->count_restore; - 1752 473 : total.count_change += scan->count_change; - 1753 473 : total.count_remove += scan->count_remove; - 1754 473 : total.count_insert += scan->count_insert; - 1755 : } - 1756 : - 1757 79 : if (is_diff) { - 1758 7 : msg_status("\n"); - 1759 7 : msg = msg_status; - 1760 : } else { - 1761 72 : msg = msg_verbose; - 1762 : } - 1763 : - 1764 79 : msg("%8u equal\n", total.count_equal); - 1765 79 : msg("%8u moved\n", total.count_move); - 1766 79 : msg("%8u copied\n", total.count_copy); - 1767 79 : msg("%8u restored\n", total.count_restore); - 1768 79 : msg("%8u updated\n", total.count_change); - 1769 79 : msg("%8u removed\n", total.count_remove); - 1770 79 : msg("%8u added\n", total.count_insert); - 1771 : - 1772 79 : log_tag("summary:equal:%u\n", total.count_equal); - 1773 79 : log_tag("summary:moved:%u\n", total.count_move); - 1774 79 : log_tag("summary:copied:%u\n", total.count_copy); - 1775 79 : log_tag("summary:restored:%u\n", total.count_restore); - 1776 79 : log_tag("summary:updated:%u\n", total.count_change); - 1777 79 : log_tag("summary:removed:%u\n", total.count_remove); - 1778 79 : log_tag("summary:added:%u\n", total.count_insert); - 1779 : - 1780 236 : no_difference = !total.count_move && !total.count_copy && !total.count_restore - 1781 129 : && !total.count_change && !total.count_remove && !total.count_insert; - 1782 : - 1783 79 : if (is_diff) { - 1784 7 : if (no_difference) { - 1785 1 : msg_status("No differences\n"); - 1786 : } else { - 1787 6 : msg_status("There are differences!\n"); - 1788 : } - 1789 : } - 1790 : - 1791 79 : if (no_difference) { - 1792 9 : log_tag("summary:exit:equal\n"); - 1793 : } else { - 1794 70 : log_tag("summary:exit:diff\n"); - 1795 : } - 1796 79 : log_flush(); - 1797 : - 1798 79 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free); - 1799 : - 1800 : /* check the filesystem on all disks */ - 1801 79 : state_fscheck(state, "after scan"); + 1634 449 : if (scan->count_equal == 0 + 1635 60 : && scan->count_move == 0 + 1636 60 : && scan->count_restore == 0 + 1637 60 : && (scan->count_remove != 0 || scan->count_change != 0) + 1638 : ) { + 1639 1 : if (!done) { + 1640 1 : done = 1; + 1641 1 : log_fatal("WARNING! All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir); + 1642 : } else { + 1643 0 : log_fatal(", disk '%s' at dir '%s'", disk->name, disk->dir); + 1644 : } + 1645 : + 1646 : /* detect the special condition of all files missing */ + 1647 1 : if (scan->count_change == 0) + 1648 1 : all_missing = 1; + 1649 : + 1650 : /* detect the special condition of all files rewritten */ + 1651 1 : if (scan->count_remove == 0) + 1652 0 : all_rewritten = 1; + 1653 : } + 1654 : } + 1655 75 : if (done) { + 1656 1 : log_fatal("\nare now missing or rewritten!\n"); + 1657 1 : if (all_rewritten) { + 1658 0 : log_fatal("This could happen when restoring a disk with a backup\n"); + 1659 0 : log_fatal("program that is not setting correctly the timestamps.\n"); + 1660 : } + 1661 1 : if (all_missing) { + 1662 1 : log_fatal("This could happen when some disks are not mounted\n"); + 1663 1 : log_fatal("in the expected directory.\n"); + 1664 : } + 1665 1 : if (!is_diff) { + 1666 1 : log_fatal("If you want to '%s' anyway, use 'snapraid --force-empty %s'.", state->command, state->command); + 1667 1 : exit(EXIT_FAILURE); + 1668 : } + 1669 : } + 1670 : } + 1671 : + 1672 : /* check for disks without the physical offset support */ + 1673 79 : if (state->opt.force_order == SORT_PHYSICAL) { + 1674 2 : done = 0; + 1675 14 : for (i = state->disklist; i != 0; i = i->next) { + 1676 12 : struct snapraid_disk* disk = i->data; + 1677 : + 1678 12 : if (disk->has_unreliable_physical) { + 1679 0 : if (!done) { + 1680 0 : done = 1; + 1681 0 : log_fatal("WARNING! Physical offsets not supported for disk '%s'", disk->name); + 1682 : } else { + 1683 0 : log_fatal(", '%s'", disk->name); + 1684 : } + 1685 : } + 1686 : } + 1687 2 : if (done) { + 1688 0 : log_fatal(". Files order won't be optimal.\n"); + 1689 : } + 1690 : } + 1691 : + 1692 : /* check for disks without persistent inodes */ + 1693 79 : done = 0; + 1694 552 : for (i = state->disklist; i != 0; i = i->next) { + 1695 473 : struct snapraid_disk* disk = i->data; + 1696 : + 1697 473 : if (disk->has_volatile_inodes) { + 1698 0 : if (!done) { + 1699 0 : done = 1; + 1700 0 : log_fatal("WARNING! Inodes are not persistent for disks: '%s'", disk->name); + 1701 : } else { + 1702 0 : log_fatal(", '%s'", disk->name); + 1703 : } + 1704 : } + 1705 : } + 1706 79 : if (done) { + 1707 0 : log_fatal(". Move operations won't be optimal.\n"); + 1708 : } + 1709 : + 1710 : /* check for disks with changed UUID */ + 1711 79 : done = 0; + 1712 552 : for (i = state->disklist; i != 0; i = i->next) { + 1713 473 : struct snapraid_disk* disk = i->data; + 1714 : + 1715 : /* don't print the message if the UUID changed because before */ + 1716 : /* it was no set. */ + 1717 : /* this is the normal condition for an empty disk because it */ + 1718 : /* isn't stored */ + 1719 473 : if (disk->has_different_uuid && !disk->had_empty_uuid) { + 1720 0 : if (!done) { + 1721 0 : done = 1; + 1722 0 : log_fatal("WARNING! UUID is changed for disks: '%s'", disk->name); + 1723 : } else { + 1724 0 : log_fatal(", '%s'", disk->name); + 1725 : } + 1726 : } + 1727 : } + 1728 79 : if (done) { + 1729 0 : log_fatal(". Move operations won't be optimal.\n"); + 1730 : } + 1731 : + 1732 : /* check for disks with unsupported UUID */ + 1733 79 : done = 0; + 1734 552 : for (i = state->disklist; i != 0; i = i->next) { + 1735 473 : struct snapraid_disk* disk = i->data; + 1736 : + 1737 473 : if (disk->has_unsupported_uuid) { + 1738 0 : if (!done) { + 1739 0 : done = 1; + 1740 0 : log_fatal("WARNING! UUID is unsupported for disks: '%s'", disk->name); + 1741 : } else { + 1742 0 : log_fatal(", '%s'", disk->name); + 1743 : } + 1744 : } + 1745 : } + 1746 79 : if (done) { + 1747 0 : log_fatal(". Move operations won't be optimal.\n"); + 1748 : } + 1749 : + 1750 79 : total.count_equal = 0; + 1751 79 : total.count_move = 0; + 1752 79 : total.count_copy = 0; + 1753 79 : total.count_restore = 0; + 1754 79 : total.count_change = 0; + 1755 79 : total.count_remove = 0; + 1756 79 : total.count_insert = 0; + 1757 : + 1758 552 : for (i = scanlist; i != 0; i = i->next) { + 1759 473 : struct snapraid_scan* scan = i->data; + 1760 473 : total.count_equal += scan->count_equal; + 1761 473 : total.count_move += scan->count_move; + 1762 473 : total.count_copy += scan->count_copy; + 1763 473 : total.count_restore += scan->count_restore; + 1764 473 : total.count_change += scan->count_change; + 1765 473 : total.count_remove += scan->count_remove; + 1766 473 : total.count_insert += scan->count_insert; + 1767 : } + 1768 : + 1769 79 : if (is_diff) { + 1770 7 : msg_status("\n"); + 1771 7 : msg = msg_status; + 1772 : } else { + 1773 72 : msg = msg_verbose; + 1774 : } + 1775 : + 1776 79 : msg("%8u equal\n", total.count_equal); + 1777 79 : msg("%8u moved\n", total.count_move); + 1778 79 : msg("%8u copied\n", total.count_copy); + 1779 79 : msg("%8u restored\n", total.count_restore); + 1780 79 : msg("%8u updated\n", total.count_change); + 1781 79 : msg("%8u removed\n", total.count_remove); + 1782 79 : msg("%8u added\n", total.count_insert); + 1783 : + 1784 79 : log_tag("summary:equal:%u\n", total.count_equal); + 1785 79 : log_tag("summary:moved:%u\n", total.count_move); + 1786 79 : log_tag("summary:copied:%u\n", total.count_copy); + 1787 79 : log_tag("summary:restored:%u\n", total.count_restore); + 1788 79 : log_tag("summary:updated:%u\n", total.count_change); + 1789 79 : log_tag("summary:removed:%u\n", total.count_remove); + 1790 79 : log_tag("summary:added:%u\n", total.count_insert); + 1791 : + 1792 236 : no_difference = !total.count_move && !total.count_copy && !total.count_restore + 1793 129 : && !total.count_change && !total.count_remove && !total.count_insert; + 1794 : + 1795 79 : if (is_diff) { + 1796 7 : if (no_difference) { + 1797 1 : msg_status("No differences\n"); + 1798 : } else { + 1799 6 : msg_status("There are differences!\n"); + 1800 : } + 1801 : } 1802 : - 1803 79 : if (is_diff) { - 1804 : /* check for file difference */ - 1805 7 : if (!no_difference) - 1806 6 : return 1; - 1807 : - 1808 : /* check also for incomplete "sync" */ - 1809 1 : if (parity_is_invalid(state)) - 1810 0 : return 1; - 1811 : } - 1812 : - 1813 73 : return 0; - 1814 : } - 1815 : - 1816 7 : int state_diff(struct snapraid_state* state) - 1817 : { - 1818 7 : return state_diffscan(state, 1); - 1819 : } - 1820 : - 1821 73 : void state_scan(struct snapraid_state* state) - 1822 : { - 1823 73 : (void)state_diffscan(state, 0); /* ignore return value */ - 1824 72 : } - 1825 : + 1803 79 : if (no_difference) { + 1804 9 : log_tag("summary:exit:equal\n"); + 1805 : } else { + 1806 70 : log_tag("summary:exit:diff\n"); + 1807 : } + 1808 79 : log_flush(); + 1809 : + 1810 79 : tommy_list_foreach(&scanlist, (tommy_foreach_func*)free); + 1811 : + 1812 : /* check the filesystem on all disks */ + 1813 79 : state_fscheck(state, "after scan"); + 1814 : + 1815 79 : if (is_diff) { + 1816 : /* check for file difference */ + 1817 7 : if (!no_difference) + 1818 6 : return 1; + 1819 : + 1820 : /* check also for incomplete "sync" */ + 1821 1 : if (parity_is_invalid(state)) + 1822 0 : return 1; + 1823 : } + 1824 : + 1825 73 : return 0; + 1826 : } + 1827 : + 1828 7 : int state_diff(struct snapraid_state* state) + 1829 : { + 1830 7 : return state_diffscan(state, 1); + 1831 : } + 1832 : + 1833 73 : void state_scan(struct snapraid_state* state) + 1834 : { + 1835 73 : (void)state_diffscan(state, 0); /* ignore return value */ + 1836 72 : } + 1837 : diff --git a/cov/cmdline/scrub.c.func-sort-c.html b/cov/cmdline/scrub.c.func-sort-c.html index 9ecf00a2..a40ea5f0 100644 --- a/cov/cmdline/scrub.c.func-sort-c.html +++ b/cov/cmdline/scrub.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/cmdline/scrub.c.func.html b/cov/cmdline/scrub.c.func.html index 7a283e31..9815b4ce 100644 --- a/cov/cmdline/scrub.c.func.html +++ b/cov/cmdline/scrub.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/cmdline/scrub.c.gcov.html b/cov/cmdline/scrub.c.gcov.html index 6e6097d8..751e79a9 100644 --- a/cov/cmdline/scrub.c.gcov.html +++ b/cov/cmdline/scrub.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -122,12 +122,12 @@ 60 : 61 : /* bad blocks are always scrubbed in all plans */ 62 111818 : if (info_get_bad(info)) - 63 3606 : return 1; + 63 3604 : return 1; 64 : - 65 108212 : switch (plan->plan) { + 65 108214 : switch (plan->plan) { 66 : case SCRUB_FULL : 67 : /* in 'full' plan everything is scrubbed */ - 68 16918 : return 1; + 68 16920 : return 1; 69 : case SCRUB_EVEN : 70 : /* in 'even' plan, scrub only even blocks */ 71 18398 : return i % 2 == 0; @@ -143,19 +143,19 @@ 81 56052 : blocktime = info_get_time(info); 82 56052 : if (blocktime > plan->timelimit) { 83 : /* skip it */ - 84 20666 : return 0; + 84 22506 : return 0; 85 : } 86 : 87 : /* if the time is less than the limit, always include */ 88 : /* otherwise, check if we reached the last limit count */ - 89 35386 : if (blocktime == plan->timelimit) { + 89 33546 : if (blocktime == plan->timelimit) { 90 : /* if we reached the count limit */ - 91 18912 : if (plan->countlast >= plan->lastlimit) { + 91 16872 : if (plan->countlast >= plan->lastlimit) { 92 : /* skip it */ - 93 13722 : return 0; + 93 11882 : return 0; 94 : } 95 : - 96 5190 : ++plan->countlast; + 96 4990 : ++plan->countlast; 97 : } 98 : 99 21664 : return 1; @@ -304,9 +304,9 @@ 242 : /* if the file is different than the current one, close it */ 243 166241 : if (handle[j].file != 0 && handle[j].file != file) { 244 : /* keep a pointer at the file we are going to close for error reporting */ - 245 78213 : struct snapraid_file* report = handle[j].file; - 246 78213 : ret = handle_close(&handle[j]); - 247 78213 : if (ret == -1) { + 245 78552 : struct snapraid_file* report = handle[j].file; + 246 78552 : ret = handle_close(&handle[j]); + 247 78552 : if (ret == -1) { 248 : /* LCOV_EXCL_START */ 249 : /* This one is really an unexpected error, because we are only reading */ 250 : /* and closing a descriptor should never fail */ @@ -351,12 +351,12 @@ 289 : /* check if the file is changed */ 290 166241 : if (handle[j].st.st_size != file->size 291 166241 : || handle[j].st.st_mtime != file->mtime_sec - 292 160519 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec + 292 160522 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec 293 : /* don't check the inode to support filesystem without persistent inodes */ 294 : ) { 295 : /* report that the block and the file are not synced */ - 296 5722 : block_is_unsynced = 1; - 297 5722 : file_is_unsynced = 1; + 296 5719 : block_is_unsynced = 1; + 297 5719 : file_is_unsynced = 1; 298 : /* follow */ 299 : } 300 : @@ -728,12 +728,12 @@ 666 : /* output the info map */ 667 11 : i = 0; 668 11 : log_tag("info_count:%u\n", count); - 669 51 : while (i < count) { - 670 29 : unsigned j = i + 1; - 671 55938 : while (j < count && timemap[i] == timemap[j]) - 672 55880 : ++j; - 673 29 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i); - 674 29 : i = j; + 669 54 : while (i < count) { + 670 32 : unsigned j = i + 1; + 671 55941 : while (j < count && timemap[i] == timemap[j]) + 672 55877 : ++j; + 673 32 : log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i); + 674 32 : i = j; 675 : } 676 : 677 : /* compute the limits from count/recentlimit */ @@ -754,8 +754,8 @@ 692 : /* count how many entries for this exact time we have to scrub */ 693 : /* if the blocks have all the same time, we end with countlimit == lastlimit */ 694 5 : ps.lastlimit = 1; - 695 2600 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit) - 696 2590 : ++ps.lastlimit; + 695 2500 : while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit) + 696 2490 : ++ps.lastlimit; 697 : } else { 698 : /* if nothing to scrub, disable also other limits */ 699 1 : ps.timelimit = 0; @@ -763,53 +763,52 @@ 701 : } 702 : 703 6 : log_tag("count_limit:%u\n", countlimit); - 704 : } - 705 : - 706 11 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit); - 707 11 : log_tag("last_limit:%u\n", ps.lastlimit); - 708 : - 709 : /* free the temp vector */ - 710 11 : free(timemap); - 711 : - 712 : /* open the file for reading */ - 713 77 : for (l = 0; l < state->level; ++l) { - 714 66 : parity_ptr[l] = &parity[l]; - 715 66 : ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode); - 716 66 : if (ret == -1) { - 717 : /* LCOV_EXCL_START */ - 718 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l)); - 719 : exit(EXIT_FAILURE); - 720 : /* LCOV_EXCL_STOP */ - 721 : } - 722 : } - 723 : - 724 11 : msg_progress("Scrubbing...\n"); - 725 : - 726 11 : error = 0; - 727 : - 728 11 : ret = state_scrub_process(state, parity_ptr, 0, blockmax, &ps, now); - 729 11 : if (ret == -1) { - 730 0 : ++error; - 731 : /* continue, as we are already exiting */ - 732 : } - 733 : - 734 77 : for (l = 0; l < state->level; ++l) { - 735 66 : ret = parity_close(parity_ptr[l]); - 736 66 : if (ret == -1) { - 737 : /* LCOV_EXCL_START */ - 738 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); - 739 : ++error; - 740 : /* continue, as we are already exiting */ - 741 : /* LCOV_EXCL_STOP */ - 742 : } - 743 : } - 744 : - 745 : /* abort if required */ - 746 11 : if (error != 0) - 747 0 : return -1; - 748 11 : return 0; - 749 : } - 750 : + 704 6 : log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit); + 705 6 : log_tag("last_limit:%u\n", ps.lastlimit); + 706 : } + 707 : + 708 : /* free the temp vector */ + 709 11 : free(timemap); + 710 : + 711 : /* open the file for reading */ + 712 77 : for (l = 0; l < state->level; ++l) { + 713 66 : parity_ptr[l] = &parity[l]; + 714 66 : ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode); + 715 66 : if (ret == -1) { + 716 : /* LCOV_EXCL_START */ + 717 : log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l)); + 718 : exit(EXIT_FAILURE); + 719 : /* LCOV_EXCL_STOP */ + 720 : } + 721 : } + 722 : + 723 11 : msg_progress("Scrubbing...\n"); + 724 : + 725 11 : error = 0; + 726 : + 727 11 : ret = state_scrub_process(state, parity_ptr, 0, blockmax, &ps, now); + 728 11 : if (ret == -1) { + 729 0 : ++error; + 730 : /* continue, as we are already exiting */ + 731 : } + 732 : + 733 77 : for (l = 0; l < state->level; ++l) { + 734 66 : ret = parity_close(parity_ptr[l]); + 735 66 : if (ret == -1) { + 736 : /* LCOV_EXCL_START */ + 737 : log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); + 738 : ++error; + 739 : /* continue, as we are already exiting */ + 740 : /* LCOV_EXCL_STOP */ + 741 : } + 742 : } + 743 : + 744 : /* abort if required */ + 745 11 : if (error != 0) + 746 0 : return -1; + 747 11 : return 0; + 748 : } + 749 : diff --git a/cov/cmdline/search.c.func-sort-c.html b/cov/cmdline/search.c.func-sort-c.html index 1b6afc8f..29c53774 100644 --- a/cov/cmdline/search.c.func-sort-c.html +++ b/cov/cmdline/search.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 @@ -61,15 +61,15 @@ search_file - 1842333 + 1842576 search_file_free - 1842333 + 1842576 state_search_fetch - 630950 + 630482 search_file_compare diff --git a/cov/cmdline/search.c.func.html b/cov/cmdline/search.c.func.html index 1ec32225..7773723e 100644 --- a/cov/cmdline/search.c.func.html +++ b/cov/cmdline/search.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 @@ -65,7 +65,7 @@ search_file - 1842333 + 1842576 search_file_compare @@ -73,7 +73,7 @@ search_file_free - 1842333 + 1842576 state_search @@ -85,7 +85,7 @@ state_search_fetch - 630950 + 630482
diff --git a/cov/cmdline/search.c.gcov.html b/cov/cmdline/search.c.gcov.html index 4ffd440f..ae597b03 100644 --- a/cov/cmdline/search.c.gcov.html +++ b/cov/cmdline/search.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 @@ -85,27 +85,27 @@ 23 : /****************************************************************************/ 24 : /* search */ 25 : - 26 1842333 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec) + 26 1842576 : static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec) 27 : { 28 : struct snapraid_search_file* file; 29 : tommy_uint32_t file_hash; 30 : - 31 1842333 : file = malloc_nofail(sizeof(struct snapraid_search_file)); - 32 1842333 : file->path = strdup_nofail(path); - 33 1842333 : file->size = size; - 34 1842333 : file->mtime_sec = mtime_sec; - 35 1842333 : file->mtime_nsec = mtime_nsec; + 31 1842576 : file = malloc_nofail(sizeof(struct snapraid_search_file)); + 32 1842576 : file->path = strdup_nofail(path); + 33 1842576 : file->size = size; + 34 1842576 : file->mtime_sec = mtime_sec; + 35 1842576 : file->mtime_nsec = mtime_nsec; 36 : - 37 1842333 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); + 37 1842576 : file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec); 38 : - 39 1842333 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash); - 40 1842333 : } + 39 1842576 : tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash); + 40 1842576 : } 41 : - 42 1842333 : void search_file_free(struct snapraid_search_file* file) + 42 1842576 : void search_file_free(struct snapraid_search_file* file) 43 : { - 44 1842333 : free(file->path); - 45 1842333 : free(file); - 46 1842333 : } + 44 1842576 : free(file->path); + 45 1842576 : free(file); + 46 1842576 : } 47 : 48 : struct search_file_compare_arg { 49 : const struct snapraid_state* state; @@ -176,9 +176,9 @@ 114 : 115 : /* compute the hash */ 116 11531 : if (arg->prevhash) - 117 4483 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size); + 117 4492 : memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size); 118 : else - 119 7048 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size); + 119 7039 : memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size); 120 : 121 : /* check if the hash is matching */ 122 11531 : if (memcmp(buffer_hash, arg->block->hash, HASH_SIZE) != 0) @@ -192,26 +192,26 @@ 130 9412 : return 0; 131 : } 132 : - 133 630950 : int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer) + 133 630482 : int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer) 134 : { 135 : struct snapraid_search_file* file; 136 : tommy_uint32_t file_hash; 137 : struct search_file_compare_arg arg; 138 : - 139 630950 : arg.state = state; - 140 630950 : arg.block = missing_block; - 141 630950 : arg.file = missing_file; - 142 630950 : arg.buffer = buffer; - 143 630950 : arg.offset = state->block_size * (data_off_t)missing_file_pos; - 144 630950 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size); - 145 630950 : arg.prevhash = prevhash; + 139 630482 : arg.state = state; + 140 630482 : arg.block = missing_block; + 141 630482 : arg.file = missing_file; + 142 630482 : arg.buffer = buffer; + 143 630482 : arg.offset = state->block_size * (data_off_t)missing_file_pos; + 144 630482 : arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size); + 145 630482 : arg.prevhash = prevhash; 146 : - 147 630950 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec); + 147 630482 : file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec); 148 : 149 : /* search in the hashtable, and also check if the data matches the hash */ - 150 630950 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash); - 151 630950 : if (!file) - 152 621538 : return -1; + 150 630482 : file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash); + 151 630482 : if (!file) + 152 621070 : return -1; 153 : 154 : /* if found, buffer is already set with data */ 155 9412 : return 0; @@ -233,40 +233,40 @@ 171 : char path_next[PATH_MAX]; 172 : char sub_next[PATH_MAX]; 173 : char out[PATH_MAX]; - 174 2039139 : struct snapraid_filter* reason = 0; + 174 2039164 : struct snapraid_filter* reason = 0; 175 : struct stat st; 176 : const char* name; 177 : struct dirent* dd; 178 : 179 : /* clear errno to detect erroneous conditions */ - 180 2039139 : errno = 0; - 181 2039139 : dd = readdir(d); - 182 2039139 : if (dd == 0 && errno != 0) { + 180 2039164 : errno = 0; + 181 2039164 : dd = readdir(d); + 182 2039164 : if (dd == 0 && errno != 0) { 183 : /* LCOV_EXCL_START */ 184 : log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno)); 185 : exit(EXIT_FAILURE); 186 : /* LCOV_EXCL_STOP */ 187 : } - 188 2039139 : if (dd == 0) { + 188 2039164 : if (dd == 0) { 189 2462 : break; /* finished */ 190 : } 191 : 192 : /* skip "." and ".." files */ - 193 2036677 : name = dd->d_name; - 194 2036677 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + 193 2036702 : name = dd->d_name; + 194 2036702 : if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) 195 9848 : continue; 196 : - 197 2031753 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); - 198 2031753 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); + 197 2031778 : pathprint(path_next, sizeof(path_next), "%s%s", dir, name); + 198 2031778 : pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); 199 : 200 : /* exclude hidden files even before calling lstat() */ - 201 2031753 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) { + 201 2031778 : if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) { 202 0 : msg_verbose("Excluding hidden '%s'\n", path_next); 203 0 : continue; 204 : } 205 : 206 : /* exclude content files even before calling lstat() */ - 207 2031753 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) { + 207 2031778 : if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) { 208 0 : msg_verbose("Excluding content '%s'\n", path_next); 209 0 : continue; 210 : } @@ -290,7 +290,7 @@ 228 : } 229 : #else 230 : /* get lstat info about the file */ - 231 2031753 : if (lstat(path_next, &st) != 0) { + 231 2031778 : if (lstat(path_next, &st) != 0) { 232 : /* LCOV_EXCL_START */ 233 : log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); 234 : exit(EXIT_FAILURE); @@ -298,13 +298,13 @@ 236 : } 237 : #endif 238 : - 239 2031753 : if (S_ISREG(st.st_mode)) { - 240 1967420 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { - 241 1842333 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st)); + 239 2031778 : if (S_ISREG(st.st_mode)) { + 240 1967521 : if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { + 241 1842576 : search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st)); 242 : } else { - 243 125087 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); + 243 124945 : msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); 244 : } - 245 64333 : } else if (S_ISDIR(st.st_mode)) { + 245 64257 : } else if (S_ISDIR(st.st_mode)) { 246 1781 : if (disk == 0 || filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) { 247 1781 : pathslash(path_next, sizeof(path_next)); 248 1781 : pathslash(sub_next, sizeof(sub_next)); @@ -313,7 +313,7 @@ 251 0 : msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); 252 : } 253 : } - 254 2036677 : } + 254 2036702 : } 255 : 256 2462 : if (closedir(d) != 0) { 257 : /* LCOV_EXCL_START */ diff --git a/cov/cmdline/selftest.c.func-sort-c.html b/cov/cmdline/selftest.c.func-sort-c.html index d7482c19..cbbf9134 100644 --- a/cov/cmdline/selftest.c.func-sort-c.html +++ b/cov/cmdline/selftest.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 diff --git a/cov/cmdline/selftest.c.func.html b/cov/cmdline/selftest.c.func.html index a8b2aced..7dd73f90 100644 --- a/cov/cmdline/selftest.c.func.html +++ b/cov/cmdline/selftest.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 diff --git a/cov/cmdline/selftest.c.gcov.html b/cov/cmdline/selftest.c.gcov.html index ec21e5a0..c18817e6 100644 --- a/cov/cmdline/selftest.c.gcov.html +++ b/cov/cmdline/selftest.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 diff --git a/cov/cmdline/snapraid.c.func-sort-c.html b/cov/cmdline/snapraid.c.func-sort-c.html index a2fbacb2..8601a790 100644 --- a/cov/cmdline/snapraid.c.func-sort-c.html +++ b/cov/cmdline/snapraid.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 diff --git a/cov/cmdline/snapraid.c.func.html b/cov/cmdline/snapraid.c.func.html index da1dd303..5c3cd1ce 100644 --- a/cov/cmdline/snapraid.c.func.html +++ b/cov/cmdline/snapraid.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 diff --git a/cov/cmdline/snapraid.c.gcov.html b/cov/cmdline/snapraid.c.gcov.html index 8d470dea..9efa5568 100644 --- a/cov/cmdline/snapraid.c.gcov.html +++ b/cov/cmdline/snapraid.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 8 diff --git a/cov/cmdline/speed.c.func-sort-c.html b/cov/cmdline/speed.c.func-sort-c.html index 587fdc01..af5d7d8f 100644 --- a/cov/cmdline/speed.c.func-sort-c.html +++ b/cov/cmdline/speed.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,7 +61,7 @@ diffgettimeofday - 1861 + 1866 speed diff --git a/cov/cmdline/speed.c.func.html b/cov/cmdline/speed.c.func.html index 674c7d66..eb03f6a4 100644 --- a/cov/cmdline/speed.c.func.html +++ b/cov/cmdline/speed.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,7 +61,7 @@ diffgettimeofday - 1861 + 1866 speed diff --git a/cov/cmdline/speed.c.gcov.html b/cov/cmdline/speed.c.gcov.html index e10bd832..edf49280 100644 --- a/cov/cmdline/speed.c.gcov.html +++ b/cov/cmdline/speed.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -100,14 +100,14 @@ 38 : /** 39 : * Differential us of two timeval. 40 : */ - 41 1861 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop) + 41 1866 : static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop) 42 : { 43 : int64_t d; 44 : - 45 1861 : d = 1000000LL * (stop->tv_sec - start->tv_sec); - 46 1861 : d += stop->tv_usec - start->tv_usec; + 45 1866 : d = 1000000LL * (stop->tv_sec - start->tv_sec); + 46 1866 : d += stop->tv_usec - start->tv_usec; 47 : - 48 1861 : return d; + 48 1866 : return d; 49 : } 50 : 51 : /** @@ -232,10 +232,10 @@ 170 4 : printf("%8s", "memset"); 171 4 : fflush(stdout); 172 : - 173 383 : SPEED_START { - 174 3411 : for (j = 0; j < nd; ++j) - 175 3032 : memset(v[j], j, size); - 176 379 : } SPEED_STOP + 173 385 : SPEED_START { + 174 3429 : for (j = 0; j < nd; ++j) + 175 3048 : memset(v[j], j, size); + 176 381 : } SPEED_STOP 177 : 178 4 : printf("%8" PRIu64, ds / dt); 179 4 : printf("\n"); @@ -247,10 +247,10 @@ 185 4 : printf("%8s", "table"); 186 4 : fflush(stdout); 187 : - 188 44 : SPEED_START { - 189 360 : for (j = 0; j < nd; ++j) - 190 320 : side_effect += crc32c_gen(0, v[j], size); - 191 40 : } SPEED_STOP + 188 46 : SPEED_START { + 189 378 : for (j = 0; j < nd; ++j) + 190 336 : side_effect += crc32c_gen(0, v[j], size); + 191 42 : } SPEED_STOP 192 : 193 4 : printf("%8" PRIu64, ds / dt); 194 4 : printf("\n"); @@ -302,10 +302,10 @@ 240 4 : printf("%8" PRIu64, ds / dt); 241 4 : fflush(stdout); 242 : - 243 36 : SPEED_START { - 244 288 : for (j = 0; j < nd; ++j) - 245 256 : memhash(HASH_SPOOKY2, seed, digest, v[j], size); - 246 32 : } SPEED_STOP + 243 35 : SPEED_START { + 244 279 : for (j = 0; j < nd; ++j) + 245 248 : memhash(HASH_SPOOKY2, seed, digest, v[j], size); + 246 31 : } SPEED_STOP 247 : 248 4 : printf("%8" PRIu64, ds / dt); 249 4 : printf("\n"); @@ -358,9 +358,9 @@ 296 : #ifdef CONFIG_X86 297 : #ifdef CONFIG_SSE2 298 4 : if (raid_cpu_has_sse2()) { - 299 312 : SPEED_START { - 300 308 : raid_gen1_sse2(nd, size, v); - 301 308 : } SPEED_STOP + 299 310 : SPEED_START { + 300 306 : raid_gen1_sse2(nd, size, v); + 301 306 : } SPEED_STOP 302 : 303 4 : printf("%8" PRIu64, ds / dt); 304 4 : fflush(stdout); @@ -411,9 +411,9 @@ 349 : #ifdef CONFIG_X86 350 : #ifdef CONFIG_SSE2 351 4 : if (raid_cpu_has_sse2()) { - 352 148 : SPEED_START { - 353 144 : raid_gen2_sse2(nd, size, v); - 354 144 : } SPEED_STOP + 352 147 : SPEED_START { + 353 143 : raid_gen2_sse2(nd, size, v); + 354 143 : } SPEED_STOP 355 : 356 4 : printf("%8" PRIu64, ds / dt); 357 4 : fflush(stdout); @@ -537,9 +537,9 @@ 475 : #ifdef CONFIG_X86 476 : #ifdef CONFIG_SSSE3 477 4 : if (raid_cpu_has_ssse3()) { - 478 53 : SPEED_START { - 479 50 : raid_gen3_ssse3(nd, size, v); - 480 50 : } SPEED_STOP + 478 54 : SPEED_START { + 479 51 : raid_gen3_ssse3(nd, size, v); + 480 51 : } SPEED_STOP 481 : 482 3 : printf("%8" PRIu64, ds / dt); 483 3 : fflush(stdout); @@ -602,9 +602,9 @@ 540 : #ifdef CONFIG_X86 541 : #ifdef CONFIG_SSSE3 542 4 : if (raid_cpu_has_ssse3()) { - 543 34 : SPEED_START { - 544 31 : raid_gen4_ssse3(nd, size, v); - 545 31 : } SPEED_STOP + 543 36 : SPEED_START { + 544 33 : raid_gen4_ssse3(nd, size, v); + 545 33 : } SPEED_STOP 546 : 547 3 : printf("%8" PRIu64, ds / dt); 548 3 : fflush(stdout); @@ -667,9 +667,9 @@ 605 : #ifdef CONFIG_X86 606 : #ifdef CONFIG_SSSE3 607 4 : if (raid_cpu_has_ssse3()) { - 608 26 : SPEED_START { - 609 23 : raid_gen5_ssse3(nd, size, v); - 610 23 : } SPEED_STOP + 608 27 : SPEED_START { + 609 24 : raid_gen5_ssse3(nd, size, v); + 610 24 : } SPEED_STOP 611 : 612 3 : printf("%8" PRIu64, ds / dt); 613 3 : fflush(stdout); @@ -707,9 +707,9 @@ 645 4 : printf("%8s", raid_gen6_tag()); 646 4 : fflush(stdout); 647 : - 648 9 : SPEED_START { - 649 5 : raid_gen6_int8(nd, size, v); - 650 5 : } SPEED_STOP + 648 10 : SPEED_START { + 649 6 : raid_gen6_int8(nd, size, v); + 650 6 : } SPEED_STOP 651 : 652 4 : printf("%8" PRIu64, ds / dt); 653 4 : fflush(stdout); diff --git a/cov/cmdline/spooky2.c.func-sort-c.html b/cov/cmdline/spooky2.c.func-sort-c.html index ccc7db47..d52512e6 100644 --- a/cov/cmdline/spooky2.c.func-sort-c.html +++ b/cov/cmdline/spooky2.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 @@ -61,7 +61,7 @@ SpookyHash128 - 3470873 + 3472174
diff --git a/cov/cmdline/spooky2.c.func.html b/cov/cmdline/spooky2.c.func.html index 8b3213dc..d22d4cbf 100644 --- a/cov/cmdline/spooky2.c.func.html +++ b/cov/cmdline/spooky2.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 @@ -61,7 +61,7 @@ SpookyHash128 - 3470873 + 3472174
diff --git a/cov/cmdline/spooky2.c.gcov.html b/cov/cmdline/spooky2.c.gcov.html index b8c57bca..06596abb 100644 --- a/cov/cmdline/spooky2.c.gcov.html +++ b/cov/cmdline/spooky2.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 @@ -170,7 +170,7 @@ 108 : // 109 : #define sc_const 0xdeadbeefdeadbeefLL 110 : - 111 3470873 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest) + 111 3472174 : void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest) 112 : { 113 : uint64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11; 114 : uint64_t buf[sc_numVars]; @@ -182,39 +182,39 @@ 120 : unsigned i; 121 : #endif 122 : - 123 3470873 : h9 = ((const uint64_t*)seed)[0]; - 124 3470873 : h10 = ((const uint64_t*)seed)[1]; + 123 3472174 : h9 = ((const uint64_t*)seed)[0]; + 124 3472174 : h10 = ((const uint64_t*)seed)[1]; 125 : 126 : #if WORDS_BIGENDIAN 127 : h9 = util_swap64(h9); 128 : h10 = util_swap64(h10); 129 : #endif 130 : - 131 3470873 : h0 = h3 = h6 = h9; - 132 3470873 : h1 = h4 = h7 = h10; - 133 3470873 : h2 = h5 = h8 = h11 = sc_const; + 131 3472174 : h0 = h3 = h6 = h9; + 132 3472174 : h1 = h4 = h7 = h10; + 133 3472174 : h2 = h5 = h8 = h11 = sc_const; 134 : - 135 3470873 : nblocks = size / sc_blockSize; - 136 3470873 : blocks = data; - 137 3470873 : end = blocks + nblocks * sc_numVars; + 135 3472174 : nblocks = size / sc_blockSize; + 136 3472174 : blocks = data; + 137 3472174 : end = blocks + nblocks * sc_numVars; 138 : 139 : /* body */ - 140 34954199 : while (blocks < end) { + 140 34945798 : while (blocks < end) { 141 : #if WORDS_BIGENDIAN 142 : for (i = 0; i < sc_numVars; ++i) 143 : buf[i] = util_swap64(blocks[i]); 144 : Mix(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); 145 : #else - 146 28012453 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); + 146 28001450 : Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); 147 : #endif - 148 28012453 : blocks += sc_numVars; + 148 28001450 : blocks += sc_numVars; 149 : } 150 : 151 : /* tail */ - 152 3470873 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data)); - 153 3470873 : memcpy(buf, end, size_remainder); - 154 3470873 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder); - 155 3470873 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder; + 152 3472174 : size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data)); + 153 3472174 : memcpy(buf, end, size_remainder); + 154 3472174 : memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder); + 155 3472174 : ((uint8_t*)buf)[sc_blockSize - 1] = size_remainder; 156 : 157 : /* finalization */ 158 : #if WORDS_BIGENDIAN @@ -222,16 +222,16 @@ 160 : buf[i] = util_swap64(buf[i]); 161 : #endif 162 : - 163 3470873 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); + 163 3472174 : End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); 164 : 165 : #if WORDS_BIGENDIAN 166 : h0 = util_swap64(h0); 167 : h1 = util_swap64(h1); 168 : #endif 169 : - 170 3470873 : ((uint64_t*)digest)[0] = h0; - 171 3470873 : ((uint64_t*)digest)[1] = h1; - 172 3470873 : } + 170 3472174 : ((uint64_t*)digest)[0] = h0; + 171 3472174 : ((uint64_t*)digest)[1] = h1; + 172 3472174 : } 173 : diff --git a/cov/cmdline/state.c.func-sort-c.html b/cov/cmdline/state.c.func-sort-c.html index cd64a35b..7cf9b431 100644 --- a/cov/cmdline/state.c.func-sort-c.html +++ b/cov/cmdline/state.c.func-sort-c.html @@ -31,13 +31,13 @@ lcov.info Lines: - 1249 + 1248 1351 - 92.5 % + 92.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 35 @@ -61,7 +61,7 @@ fs_is_block_deleted_ts - 29383119 + 29344162 fs_info_is_required @@ -69,7 +69,7 @@ state_progress - 1038828 + 1038958 fs_position_is_required @@ -77,7 +77,7 @@ lev_config_name - 178770 + 178766 find_disk @@ -93,7 +93,7 @@ state_verify_thread - 908 + 912 state_fscheck diff --git a/cov/cmdline/state.c.func.html b/cov/cmdline/state.c.func.html index 38f32f80..c610d3af 100644 --- a/cov/cmdline/state.c.func.html +++ b/cov/cmdline/state.c.func.html @@ -31,13 +31,13 @@ lcov.info Lines: - 1249 + 1248 1351 - 92.5 % + 92.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 35 @@ -73,7 +73,7 @@ fs_is_block_deleted_ts - 29383119 + 29344162 fs_position_clear_deleted @@ -89,7 +89,7 @@ lev_config_name - 178770 + 178766 lev_config_scan @@ -137,7 +137,7 @@ state_progress - 1038828 + 1038958 state_progress_begin @@ -185,7 +185,7 @@ state_verify_thread - 908 + 912 state_write diff --git a/cov/cmdline/state.c.gcov.html b/cov/cmdline/state.c.gcov.html index c8394e94..17e83360 100644 --- a/cov/cmdline/state.c.gcov.html +++ b/cov/cmdline/state.c.gcov.html @@ -31,13 +31,13 @@ lcov.info Lines: - 1249 + 1248 1351 - 92.5 % + 92.4 % Date: - 2015-11-13 + 2015-11-20 Functions: 35 @@ -103,10 +103,10 @@ 41 0 : return 0; 42 : } 43 : - 44 178770 : const char* lev_config_name(unsigned l) + 44 178766 : const char* lev_config_name(unsigned l) 45 : { - 46 178770 : switch (l) { - 47 70480 : case 0 : return "parity"; + 46 178766 : switch (l) { + 47 70476 : case 0 : return "parity"; 48 57423 : case 1 : return "2-parity"; 49 12723 : case 2 : return "3-parity"; 50 12719 : case 3 : return "4-parity"; @@ -1592,11 +1592,11 @@ 1530 : /** 1531 : * Check if a block position in a disk is deleted. 1532 : */ - 1533 29383119 : static int fs_is_block_deleted_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t pos) + 1533 29344162 : static int fs_is_block_deleted_ts(struct snapraid_disk* disk, struct snapraid_chunk** fs_last, block_off_t pos) 1534 : { - 1535 29383119 : struct snapraid_block* block = fs_par2block_get_ts(disk, fs_last, pos); + 1535 29344162 : struct snapraid_block* block = fs_par2block_get_ts(disk, fs_last, pos); 1536 : - 1537 29381514 : return block_state_get(block) == BLOCK_STATE_DELETED; + 1537 29163541 : return block_state_get(block) == BLOCK_STATE_DELETED; 1538 : } 1539 : 1540 : /** @@ -1706,12 +1706,12 @@ 1644 : int c; 1645 : 1646 : /* read the command */ - 1647 3604981 : c = sgetc(f); - 1648 3604981 : if (c == EOF) { + 1647 3605061 : c = sgetc(f); + 1648 3605061 : if (c == EOF) { 1649 234 : break; 1650 : } 1651 : - 1652 3604747 : if (c == 'f') { + 1652 3604827 : if (c == 'f') { 1653 : /* file */ 1654 : char sub[PATH_MAX]; 1655 : uint64_t v_size; @@ -1723,18 +1723,18 @@ 1661 : struct snapraid_disk* disk; 1662 : uint32_t mapping; 1663 : - 1664 3485836 : ret = sgetb32(f, &mapping); - 1665 3485836 : if (ret < 0 || mapping >= mapping_max) { + 1664 3485915 : ret = sgetb32(f, &mapping); + 1665 3485915 : if (ret < 0 || mapping >= mapping_max) { 1666 : /* LCOV_EXCL_START */ 1667 : decoding_error(path, f); 1668 : log_fatal("Internal inconsistency in mapping index!\n"); 1669 : exit(EXIT_FAILURE); 1670 : /* LCOV_EXCL_STOP */ 1671 : } - 1672 3485836 : disk = tommy_array_get(&disk_mapping, mapping); + 1672 3485915 : disk = tommy_array_get(&disk_mapping, mapping); 1673 : - 1674 3485836 : ret = sgetb64(f, &v_size); - 1675 3485836 : if (ret < 0) { + 1674 3485915 : ret = sgetb64(f, &v_size); + 1675 3485915 : if (ret < 0) { 1676 : /* LCOV_EXCL_START */ 1677 : decoding_error(path, f); 1678 : exit(EXIT_FAILURE); @@ -1742,7 +1742,7 @@ 1680 : } 1681 : 1682 : /* check for impossible file size to avoid to crash for a too big allocation */ - 1683 3485836 : if (v_size / state->block_size > blockmax) { + 1683 3485915 : if (v_size / state->block_size > blockmax) { 1684 : /* LCOV_EXCL_START */ 1685 : decoding_error(path, f); 1686 : log_fatal("Internal inconsistency in file size too big!\n"); @@ -1750,16 +1750,16 @@ 1688 : /* LCOV_EXCL_STOP */ 1689 : } 1690 : - 1691 3485836 : ret = sgetb64(f, &v_mtime_sec); - 1692 3485836 : if (ret < 0) { + 1691 3485915 : ret = sgetb64(f, &v_mtime_sec); + 1692 3485915 : if (ret < 0) { 1693 : /* LCOV_EXCL_START */ 1694 : decoding_error(path, f); 1695 : exit(EXIT_FAILURE); 1696 : /* LCOV_EXCL_STOP */ 1697 : } 1698 : - 1699 3485836 : ret = sgetb32(f, &v_mtime_nsec); - 1700 3485836 : if (ret < 0) { + 1699 3485915 : ret = sgetb32(f, &v_mtime_nsec); + 1700 3485915 : if (ret < 0) { 1701 : /* LCOV_EXCL_START */ 1702 : decoding_error(path, f); 1703 : exit(EXIT_FAILURE); @@ -1767,27 +1767,27 @@ 1705 : } 1706 : 1707 : /* STAT_NSEC_INVALID is encoded as 0 */ - 1708 3485836 : if (v_mtime_nsec == 0) + 1708 3485915 : if (v_mtime_nsec == 0) 1709 0 : v_mtime_nsec = STAT_NSEC_INVALID; 1710 : else - 1711 3485836 : --v_mtime_nsec; + 1711 3485915 : --v_mtime_nsec; 1712 : - 1713 3485836 : ret = sgetb64(f, &v_inode); - 1714 3485836 : if (ret < 0) { + 1713 3485915 : ret = sgetb64(f, &v_inode); + 1714 3485915 : if (ret < 0) { 1715 : /* LCOV_EXCL_START */ 1716 : decoding_error(path, f); 1717 : exit(EXIT_FAILURE); 1718 : /* LCOV_EXCL_STOP */ 1719 : } 1720 : - 1721 3485836 : ret = sgetbs(f, sub, sizeof(sub)); - 1722 3485836 : if (ret < 0) { + 1721 3485915 : ret = sgetbs(f, sub, sizeof(sub)); + 1722 3485915 : if (ret < 0) { 1723 : /* LCOV_EXCL_START */ 1724 : decoding_error(path, f); 1725 : exit(EXIT_FAILURE); 1726 : /* LCOV_EXCL_STOP */ 1727 : } - 1728 3485836 : if (!*sub) { + 1728 3485915 : if (!*sub) { 1729 : /* LCOV_EXCL_START */ 1730 : decoding_error(path, f); 1731 : exit(EXIT_FAILURE); @@ -1795,40 +1795,40 @@ 1733 : } 1734 : 1735 : /* allocate the file */ - 1736 3485836 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0); + 1736 3485915 : file = file_alloc(state->block_size, sub, v_size, v_mtime_sec, v_mtime_nsec, v_inode, 0); 1737 : 1738 : /* insert the file in the file containers */ - 1739 3485836 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); - 1740 3485836 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); - 1741 3485836 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); - 1742 3485836 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); + 1739 3485915 : tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + 1740 3485915 : tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); + 1741 3485915 : tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); + 1742 3485915 : tommy_list_insert_tail(&disk->filelist, &file->nodelist, file); 1743 : 1744 : /* read all the blocks */ - 1745 3485836 : v_idx = 0; - 1746 10477605 : while (v_idx < file->blockmax) { + 1745 3485915 : v_idx = 0; + 1746 10477653 : while (v_idx < file->blockmax) { 1747 : block_off_t v_pos; 1748 : uint32_t v_count; 1749 : 1750 : /* get the "subcommand */ - 1751 3505934 : c = sgetc(f); + 1751 3505823 : c = sgetc(f); 1752 : - 1753 3505934 : ret = sgetb32(f, &v_pos); - 1754 3505934 : if (ret < 0) { + 1753 3505823 : ret = sgetb32(f, &v_pos); + 1754 3505823 : if (ret < 0) { 1755 : /* LCOV_EXCL_START */ 1756 : decoding_error(path, f); 1757 : exit(EXIT_FAILURE); 1758 : /* LCOV_EXCL_STOP */ 1759 : } 1760 : - 1761 3505934 : ret = sgetb32(f, &v_count); - 1762 3505934 : if (ret < 0) { + 1761 3505823 : ret = sgetb32(f, &v_count); + 1762 3505823 : if (ret < 0) { 1763 : /* LCOV_EXCL_START */ 1764 : decoding_error(path, f); 1765 : exit(EXIT_FAILURE); 1766 : /* LCOV_EXCL_STOP */ 1767 : } 1768 : - 1769 3505934 : if (v_idx + v_count > file->blockmax) { + 1769 3505823 : if (v_idx + v_count > file->blockmax) { 1770 : /* LCOV_EXCL_START */ 1771 : decoding_error(path, f); 1772 : log_fatal("Internal inconsistency in block number!\n"); @@ -1836,7 +1836,7 @@ 1774 : /* LCOV_EXCL_STOP */ 1775 : } 1776 : - 1777 3505933 : if (v_pos + v_count > blockmax) { + 1777 3505823 : if (v_pos + v_count > blockmax) { 1778 : /* LCOV_EXCL_START */ 1779 : log_fatal("Internal inconsistency in block size %u/%u!\n", blockmax, v_pos + v_count); 1780 : decoding_error(path, f); @@ -1871,9 +1871,9 @@ 1809 : } 1810 : 1811 : /* read the hash only for 'blk/chg/rep', and not for 'new' */ - 1812 8573599 : if (c != 'n') { - 1813 8573599 : ret = sread(f, block->hash, HASH_SIZE); - 1814 8573599 : if (ret < 0) { + 1812 8573249 : if (c != 'n') { + 1813 8573249 : ret = sread(f, block->hash, HASH_SIZE); + 1814 8573249 : if (ret < 0) { 1815 : /* LCOV_EXCL_START */ 1816 : decoding_error(path, f); 1817 : exit(EXIT_FAILURE); @@ -1886,8 +1886,8 @@ 1824 : 1825 : /* if the block contains a hash of past data */ 1826 : /* and we are clearing such undeterminated hashes */ - 1827 8573599 : if (state->clear_past_hash - 1828 2287716 : && block_has_past_hash(block) + 1827 8573249 : if (state->clear_past_hash + 1828 2287366 : && block_has_past_hash(block) 1829 : ) { 1830 : /* set the hash value to INVALID */ 1831 57602 : hash_invalid_set(block->hash); @@ -1898,8 +1898,8 @@ 1836 : /* in other sync commands */ 1837 : /* note that this is required only in sync, and we detect */ 1838 : /* this using the clear_past_hash flag */ - 1839 8573599 : if (state->clear_past_hash - 1840 2287716 : && state->opt.force_nocopy + 1839 8573249 : if (state->clear_past_hash + 1840 2287366 : && state->opt.force_nocopy 1841 14115 : && block_state_get(block) == BLOCK_STATE_REP 1842 : ) { 1843 : /* set the hash value to INVALID */ @@ -1911,25 +1911,25 @@ 1849 : /* if we want a full sync, marks block as invalid parity */ 1850 : /* note that we do this after the force_nocopy option */ 1851 : /* to avoid to mixup the two things */ - 1852 8573599 : if (state->opt.force_full + 1852 8573249 : if (state->opt.force_full 1853 27746 : && block_state_get(block) == BLOCK_STATE_BLK) { 1854 : /* convert from BLK to REP */ 1855 27746 : block_state_set(block, BLOCK_STATE_REP); 1856 : } 1857 : 1858 : /* set the parity association */ - 1859 8573599 : fs_allocate(disk, v_pos, file, v_idx); + 1859 8573249 : fs_allocate(disk, v_pos, file, v_idx); 1860 : 1861 : /* go to the next block */ - 1862 8573599 : ++v_idx; - 1863 8573599 : ++v_pos; - 1864 8573599 : --v_count; + 1862 8573249 : ++v_idx; + 1863 8573249 : ++v_pos; + 1864 8573249 : --v_count; 1865 : } 1866 : } 1867 : 1868 : /* stat */ - 1869 3485835 : ++count_file; - 1870 118911 : } else if (c == 'i') { + 1869 3485915 : ++count_file; + 1870 118912 : } else if (c == 'i') { 1871 : /* "inf" command */ 1872 : snapraid_info info; 1873 : uint32_t v_pos; @@ -1944,7 +1944,7 @@ 1882 : } 1883 : 1884 234 : v_pos = 0; - 1885 284859 : while (v_pos < blockmax) { + 1885 288815 : while (v_pos < blockmax) { 1886 : int bad; 1887 : int rehash; 1888 : int justsynced; @@ -1952,15 +1952,15 @@ 1890 : uint32_t flag; 1891 : uint32_t v_count; 1892 : - 1893 284391 : ret = sgetb32(f, &v_count); - 1894 284391 : if (ret < 0) { + 1893 288347 : ret = sgetb32(f, &v_count); + 1894 288347 : if (ret < 0) { 1895 : /* LCOV_EXCL_START */ 1896 : decoding_error(path, f); 1897 : exit(EXIT_FAILURE); 1898 : /* LCOV_EXCL_STOP */ 1899 : } 1900 : - 1901 284391 : if (v_pos + v_count > blockmax) { + 1901 288347 : if (v_pos + v_count > blockmax) { 1902 : /* LCOV_EXCL_START */ 1903 : log_fatal("Internal inconsistency in info size %u/%u!\n", blockmax, v_pos + v_count); 1904 : decoding_error(path, f); @@ -1968,8 +1968,8 @@ 1906 : /* LCOV_EXCL_STOP */ 1907 : } 1908 : - 1909 284391 : ret = sgetb32(f, &flag); - 1910 284391 : if (ret < 0) { + 1909 288347 : ret = sgetb32(f, &flag); + 1910 288347 : if (ret < 0) { 1911 : /* LCOV_EXCL_START */ 1912 : decoding_error(path, f); 1913 : exit(EXIT_FAILURE); @@ -1977,10 +1977,10 @@ 1915 : } 1916 : 1917 : /* if there is an info */ - 1918 284391 : if ((flag & 1) != 0) { + 1918 288347 : if ((flag & 1) != 0) { 1919 : /* read the time */ - 1920 284376 : ret = sgetb32(f, &t); - 1921 284376 : if (ret < 0) { + 1920 288332 : ret = sgetb32(f, &t); + 1921 288332 : if (ret < 0) { 1922 : /* LCOV_EXCL_START */ 1923 : decoding_error(path, f); 1924 : exit(EXIT_FAILURE); @@ -1988,11 +1988,11 @@ 1926 : } 1927 : 1928 : /* analyze the flags */ - 1929 284376 : bad = (flag & 2) != 0; - 1930 284376 : rehash = (flag & 4) != 0; - 1931 284376 : justsynced = (flag & 8) != 0; + 1929 288332 : bad = (flag & 2) != 0; + 1930 288332 : rehash = (flag & 4) != 0; + 1931 288332 : justsynced = (flag & 8) != 0; 1932 : - 1933 284376 : if (rehash && state->prevhash == HASH_UNDEFINED) { + 1933 288332 : if (rehash && state->prevhash == HASH_UNDEFINED) { 1934 : /* LCOV_EXCL_START */ 1935 : decoding_error(path, f); 1936 : log_fatal("Internal inconsistency for missing previous checksum!\n"); @@ -2000,12 +2000,12 @@ 1938 : /* LCOV_EXCL_STOP */ 1939 : } 1940 : - 1941 284376 : info = info_make(t + v_oldest, bad, rehash, justsynced); + 1941 288332 : info = info_make(t + v_oldest, bad, rehash, justsynced); 1942 : } else { 1943 15 : info = 0; 1944 : } 1945 : - 1946 2060602 : while (v_count) { + 1946 2068514 : while (v_count) { 1947 : /* insert the info in the array */ 1948 1491820 : info_set(&state->infoarr, v_pos, info); 1949 : @@ -2028,7 +2028,7 @@ 1966 1491820 : --v_count; 1967 : } 1968 : } - 1969 118677 : } else if (c == 'h') { + 1969 118678 : } else if (c == 'h') { 1970 : /* hole */ 1971 : uint32_t v_pos; 1972 : struct snapraid_disk* disk; @@ -2074,7 +2074,7 @@ 2012 : /* if it's a run of deleted blocks */ 2013 : 2014 : /* allocate a fake deleted file */ - 2015 36 : deleted = file_alloc(state->block_size, "<deleted>", v_count * state->block_size, 0, 0, 0, 0); + 2015 36 : deleted = file_alloc(state->block_size, "<deleted>", v_count * (data_off_t)state->block_size, 0, 0, 0, 0); 2016 : 2017 : /* mark the file as deleted */ 2018 36 : file_flag_set(deleted, FILE_IS_DELETED); @@ -2126,7 +2126,7 @@ 2064 : /* LCOV_EXCL_STOP */ 2065 : } 2066 : } - 2067 117378 : } else if (c == 's') { + 2067 117379 : } else if (c == 's') { 2068 : /* symlink */ 2069 : char sub[PATH_MAX]; 2070 : char linkto[PATH_MAX]; @@ -2176,7 +2176,7 @@ 2114 : 2115 : /* stat */ 2116 112395 : ++count_symlink; - 2117 4983 : } else if (c == 'a') { + 2117 4984 : } else if (c == 'a') { 2118 : /* hardlink */ 2119 : char sub[PATH_MAX]; 2120 : char linkto[PATH_MAX]; @@ -2226,7 +2226,7 @@ 2164 : 2165 : /* stat */ 2166 567 : ++count_hardlink; - 2167 4416 : } else if (c == 'r') { + 2167 4417 : } else if (c == 'r') { 2168 : /* dir */ 2169 : char sub[PATH_MAX]; 2170 : struct snapraid_dir* dir; @@ -2267,7 +2267,7 @@ 2205 : 2206 : /* stat */ 2207 750 : ++count_dir; - 2208 3666 : } else if (c == 'c') { + 2208 3667 : } else if (c == 'c') { 2209 : /* get the subcommand */ 2210 235 : c = sgetc(f); 2211 : @@ -2294,7 +2294,7 @@ 2232 : exit(EXIT_FAILURE); 2233 : /* LCOV_EXCL_STOP */ 2234 : } - 2235 3431 : } else if (c == 'C') { + 2235 3432 : } else if (c == 'C') { 2236 : /* get the subcommand */ 2237 87 : c = sgetc(f); 2238 : @@ -2321,7 +2321,7 @@ 2259 : exit(EXIT_FAILURE); 2260 : /* LCOV_EXCL_STOP */ 2261 : } - 2262 3344 : } else if (c == 'z') { + 2262 3345 : } else if (c == 'z') { 2263 : block_off_t blksize; 2264 : 2265 235 : ret = sgetb32(f, &blksize); @@ -2345,7 +2345,7 @@ 2283 : exit(EXIT_FAILURE); 2284 : /* LCOV_EXCL_STOP */ 2285 : } - 2286 3109 : } else if (c == 'x') { + 2286 3110 : } else if (c == 'x') { 2287 235 : ret = sgetb32(f, &blockmax); 2288 235 : if (ret < 0) { 2289 : /* LCOV_EXCL_START */ @@ -2353,7 +2353,7 @@ 2291 : exit(EXIT_FAILURE); 2292 : /* LCOV_EXCL_STOP */ 2293 : } - 2294 4179 : } else if (c == 'm' || c == 'M') { + 2294 4180 : } else if (c == 'm' || c == 'M') { 2295 : struct snapraid_map* map; 2296 : char uuid[UUID_MAX]; 2297 : uint32_t v_pos; @@ -2427,7 +2427,7 @@ 2365 1305 : tommy_array_grow(&disk_mapping, mapping_max + 1); 2366 1305 : tommy_array_set(&disk_mapping, mapping_max, disk); 2367 1305 : ++mapping_max; - 2368 1569 : } else if (c == 'P') { + 2368 1570 : } else if (c == 'P') { 2369 : /* from SnapRAID 7.0 the 'P' command includes the free space */ 2370 : char uuid[UUID_MAX]; 2371 : uint32_t v_level; @@ -2477,7 +2477,7 @@ 2415 1081 : state->parity[v_level].total_blocks = v_total_blocks; 2416 1081 : state->parity[v_level].free_blocks = v_free_blocks; 2417 : } - 2418 234 : } else if (c == 'N') { + 2418 235 : } else if (c == 'N') { 2419 : uint32_t crc_stored; 2420 : uint32_t crc_computed; 2421 : @@ -2511,7 +2511,7 @@ 2449 : exit(EXIT_FAILURE); 2450 : /* LCOV_EXCL_STOP */ 2451 : } - 2452 3604746 : } + 2452 3604826 : } 2453 : 2454 234 : tommy_array_done(&disk_mapping); 2455 : @@ -2702,7 +2702,7 @@ 2640 5428 : sputb32(l, f); 2641 5428 : sputb32(state->parity[l].total_blocks, f); 2642 5428 : sputb32(state->parity[l].free_blocks, f); - 2643 5428 : sputbs(state->parity[l].uuid, f); + 2643 5427 : sputbs(state->parity[l].uuid, f); 2644 5428 : if (serror(f)) { 2645 : /* LCOV_EXCL_START */ 2646 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); @@ -2729,30 +2729,30 @@ 2667 441 : continue; 2668 : 2669 : /* for each file */ - 2670 11587893 : for (j = disk->filelist; j != 0; j = j->next) { - 2671 11582856 : struct snapraid_file* file = j->data; + 2670 11578188 : for (j = disk->filelist; j != 0; j = j->next) { + 2671 11573152 : struct snapraid_file* file = j->data; 2672 : uint64_t size; 2673 : uint64_t mtime_sec; 2674 : int32_t mtime_nsec; 2675 : uint64_t inode; 2676 : - 2677 11582856 : size = file->size; - 2678 11582856 : mtime_sec = file->mtime_sec; - 2679 11582856 : mtime_nsec = file->mtime_nsec; - 2680 11582856 : inode = file->inode; + 2677 11573152 : size = file->size; + 2678 11573152 : mtime_sec = file->mtime_sec; + 2679 11573152 : mtime_nsec = file->mtime_nsec; + 2680 11573152 : inode = file->inode; 2681 : - 2682 11582856 : sputc('f', f); - 2683 11521097 : sputb32(disk->mapping_idx, f); - 2684 11524134 : sputb64(size, f); - 2685 11502453 : sputb64(mtime_sec, f); + 2682 11573152 : sputc('f', f); + 2683 11523322 : sputb32(disk->mapping_idx, f); + 2684 11531504 : sputb64(size, f); + 2685 11543059 : sputb64(mtime_sec, f); 2686 : /* encode STAT_NSEC_INVALID as 0 */ - 2687 11514392 : if (mtime_nsec == STAT_NSEC_INVALID) + 2687 11521684 : if (mtime_nsec == STAT_NSEC_INVALID) 2688 0 : sputb32(0, f); 2689 : else - 2690 11514392 : sputb32(mtime_nsec + 1, f); - 2691 11535535 : sputb64(inode, f); - 2692 11530269 : sputbs(file->sub, f); - 2693 11528881 : if (serror(f)) { + 2690 11521684 : sputb32(mtime_nsec + 1, f); + 2691 11530611 : sputb64(inode, f); + 2692 11526825 : sputbs(file->sub, f); + 2693 11546662 : if (serror(f)) { 2694 : /* LCOV_EXCL_START */ 2695 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); 2696 : goto bail; @@ -2760,34 +2760,34 @@ 2698 : } 2699 : 2700 : /* for all the blocks of the file */ - 2701 11541902 : begin = 0; - 2702 34727907 : while (begin < file->blockmax) { - 2703 11603149 : unsigned v_state = block_state_get(fs_file2block_get(file, begin)); - 2704 11623161 : block_off_t v_pos = fs_file2par_get_ts(disk, &fs_last, file, begin); + 2701 11560751 : begin = 0; + 2702 34754559 : while (begin < file->blockmax) { + 2703 11620657 : unsigned v_state = block_state_get(fs_file2block_get(file, begin)); + 2704 11635419 : block_off_t v_pos = fs_file2par_get_ts(disk, &fs_last, file, begin); 2705 : uint32_t v_count; 2706 : 2707 : block_off_t end; 2708 : 2709 : /* find the end of run of blocks */ - 2710 11615466 : end = begin + 1; - 2711 39962808 : while (end < file->blockmax) { - 2712 16803655 : if (v_state != block_state_get(fs_file2block_get(file, end))) + 2710 11602915 : end = begin + 1; + 2711 40021161 : while (end < file->blockmax) { + 2712 16868038 : if (v_state != block_state_get(fs_file2block_get(file, end))) 2713 63 : break; - 2714 16856743 : if (v_pos + (end - begin) != fs_file2par_get_ts(disk, &fs_last, file, end)) - 2715 82936 : break; - 2716 16731876 : ++end; + 2714 16887534 : if (v_pos + (end - begin) != fs_file2par_get_ts(disk, &fs_last, file, end)) + 2715 83317 : break; + 2716 16815331 : ++end; 2717 : } 2718 : - 2719 11626686 : switch (v_state) { + 2719 11633588 : switch (v_state) { 2720 : case BLOCK_STATE_BLK : - 2721 10916510 : sputc('b', f); - 2722 10892646 : break; + 2721 10922665 : sputc('b', f); + 2722 10930254 : break; 2723 : case BLOCK_STATE_CHG : - 2724 558744 : sputc('g', f); - 2725 558725 : break; + 2724 559524 : sputc('g', f); + 2725 559519 : break; 2726 : case BLOCK_STATE_REP : - 2727 151432 : sputc('p', f); - 2728 151433 : break; + 2727 151399 : sputc('p', f); + 2728 151402 : break; 2729 : default : 2730 : /* LCOV_EXCL_START */ 2731 : log_fatal("Internal inconsistency in state for block %u state %u\n", v_pos, v_state); @@ -2795,19 +2795,19 @@ 2733 : /* LCOV_EXCL_STOP */ 2734 : } 2735 : - 2736 11602804 : sputb32(v_pos, f); + 2736 11641175 : sputb32(v_pos, f); 2737 : - 2738 11631290 : v_count = end - begin; - 2739 11631290 : sputb32(v_count, f); + 2738 11622679 : v_count = end - begin; + 2739 11622679 : sputb32(v_count, f); 2740 : 2741 : /* write hashes */ - 2742 39802834 : for (idx = begin; idx < end; ++idx) { - 2743 28167488 : struct snapraid_block* block = fs_file2block_get(file, idx); + 2742 39768736 : for (idx = begin; idx < end; ++idx) { + 2743 28155837 : struct snapraid_block* block = fs_file2block_get(file, idx); 2744 : - 2745 28196345 : swrite(block->hash, HASH_SIZE, f); + 2745 28133584 : swrite(block->hash, HASH_SIZE, f); 2746 : } 2747 : - 2748 11635346 : if (serror(f)) { + 2748 11612899 : if (serror(f)) { 2749 : /* LCOV_EXCL_START */ 2750 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); 2751 : goto bail; @@ -2815,31 +2815,31 @@ 2753 : } 2754 : 2755 : /* next begin position */ - 2756 11644103 : begin = end; + 2756 11633057 : begin = end; 2757 : } 2758 : - 2759 11582856 : ++count_file; + 2759 11573151 : ++count_file; 2760 : } 2761 : 2762 : /* for each link */ - 2763 385486 : for (j = disk->linklist; j != 0; j = j->next) { - 2764 380449 : struct snapraid_link* slink = j->data; + 2763 385485 : for (j = disk->linklist; j != 0; j = j->next) { + 2764 380448 : struct snapraid_link* slink = j->data; 2765 : - 2766 380449 : switch (link_flag_get(slink, FILE_IS_LINK_MASK)) { + 2766 380448 : switch (link_flag_get(slink, FILE_IS_LINK_MASK)) { 2767 : case FILE_IS_HARDLINK : 2768 2046 : sputc('a', f); 2769 2046 : ++count_hardlink; 2770 2046 : break; 2771 : case FILE_IS_SYMLINK : - 2772 378355 : sputc('s', f); - 2773 378402 : ++count_symlink; - 2774 378402 : break; + 2772 378402 : sputc('s', f); + 2773 378020 : ++count_symlink; + 2774 378020 : break; 2775 : } 2776 : - 2777 380132 : sputb32(disk->mapping_idx, f); - 2778 380405 : sputbs(slink->sub, f); - 2779 380450 : sputbs(slink->linkto, f); - 2780 380448 : if (serror(f)) { + 2777 380066 : sputb32(disk->mapping_idx, f); + 2778 380422 : sputbs(slink->sub, f); + 2779 380445 : sputbs(slink->linkto, f); + 2780 380449 : if (serror(f)) { 2781 : /* LCOV_EXCL_START */ 2782 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); 2783 : goto bail; @@ -2881,11 +2881,11 @@ 2819 5569 : is_deleted = fs_is_block_deleted_ts(disk, &fs_last, begin); 2820 : 2821 : /* find the end of run of blocks */ - 2822 5568 : end = begin + 1; - 2823 29329135 : while (end < blockmax - 2824 29372732 : && is_deleted == fs_is_block_deleted_ts(disk, &fs_last, end) + 2822 5569 : end = begin + 1; + 2823 29396439 : while (end < blockmax + 2824 29341613 : && is_deleted == fs_is_block_deleted_ts(disk, &fs_last, end) 2825 : ) { - 2826 29317999 : ++end; + 2826 29385301 : ++end; 2827 : } 2828 : 2829 0 : sputb32(end - begin, f); @@ -2923,45 +2923,45 @@ 2861 : /* write the info for each block */ 2862 913 : sputc('i', f); 2863 913 : sputb32(info_oldest, f); - 2864 8223 : begin = 0; - 2865 1418395 : while (begin < blockmax) { + 2864 929 : begin = 0; + 2865 1427365 : while (begin < blockmax) { 2866 : snapraid_info info; 2867 : block_off_t end; 2868 : time_t t; 2869 : unsigned flag; 2870 : - 2871 1409259 : info = info_get(&state->infoarr, begin); + 2871 1425523 : info = info_get(&state->infoarr, begin); 2872 : 2873 : /* find the end of run of blocks */ - 2874 1408072 : end = begin + 1; - 2875 6328564 : while (end < blockmax - 2876 4918189 : && info == info_get(&state->infoarr, end) + 2874 1426289 : end = begin + 1; + 2875 6350808 : while (end < blockmax + 2876 4922834 : && info == info_get(&state->infoarr, end) 2877 : ) { - 2878 3512420 : ++end; + 2878 3498230 : ++end; 2879 : } 2880 : - 2881 1407793 : sputb32(end - begin, f); + 2881 1427382 : sputb32(end - begin, f); 2882 : 2883 : /* if there is info */ - 2884 1408365 : if (info) { + 2884 1426642 : if (info) { 2885 : /* other flags */ - 2886 1408235 : flag = 1; /* info is present */ - 2887 1408235 : if (info_get_bad(info)) - 2888 9500 : flag |= 2; - 2889 1407263 : if (info_get_rehash(info)) - 2890 673630 : flag |= 4; - 2891 1406735 : if (info_get_justsynced(info)) - 2892 723766 : flag |= 8; - 2893 1398202 : sputb32(flag, f); + 2886 1426512 : flag = 1; /* info is present */ + 2887 1426512 : if (info_get_bad(info)) + 2888 9590 : flag |= 2; + 2889 1425847 : if (info_get_rehash(info)) + 2890 673003 : flag |= 4; + 2891 1425736 : if (info_get_justsynced(info)) + 2892 724485 : flag |= 8; + 2893 1425766 : sputb32(flag, f); 2894 : - 2895 1408672 : t = info_get_time(info) - info_oldest; - 2896 1408134 : sputb32(t, f); + 2895 1425741 : t = info_get_time(info) - info_oldest; + 2896 1425676 : sputb32(t, f); 2897 : } else { 2898 : /* write a special 0 flag to mark missing info */ 2899 130 : sputb32(0, f); 2900 : } 2901 : - 2902 1409231 : if (serror(f)) { + 2902 1425342 : if (serror(f)) { 2903 : /* LCOV_EXCL_START */ 2904 : log_fatal("Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); 2905 : goto bail; @@ -2969,7 +2969,7 @@ 2907 : } 2908 : 2909 : /* next begin position */ - 2910 1401949 : begin = end; + 2910 1425507 : begin = end; 2911 : } 2912 : 2913 913 : sputc('N', f); @@ -3022,7 +3022,7 @@ 2960 : } 2961 : #endif 2962 : - 2963 912 : if (sclose(f) != 0) { + 2963 913 : if (sclose(f) != 0) { 2964 : /* LCOV_EXCL_START */ 2965 : f = 0; 2966 : log_fatal("Error closing the content files. %s.\n", strerror(errno)); @@ -3084,7 +3084,7 @@ 3022 680773 : time_t info_time = info_get_time(info); 3023 : 3024 680773 : if (!info_oldest || info_time < info_oldest) - 3025 169 : info_oldest = info_time; + 3025 170 : info_oldest = info_time; 3026 : 3027 680773 : if (info_get_rehash(info)) 3028 108421 : info_has_rehash = 1; @@ -3151,7 +3151,7 @@ 3089 : /* LCOV_EXCL_STOP */ 3090 : } 3091 : #else - 3092 : content->retval = state_write_thread(context); + 3092 : context->retval = state_write_thread(context); 3093 : #endif 3094 : 3095 913 : i = i->next; @@ -3384,17 +3384,17 @@ 3322 : uint32_t crc; 3323 : }; 3324 : - 3325 908 : static void* state_verify_thread(void* arg) + 3325 912 : static void* state_verify_thread(void* arg) 3326 : { - 3327 908 : struct state_verify_thread_context* context = arg; - 3328 908 : struct snapraid_content* content = context->content; + 3327 912 : struct state_verify_thread_context* context = arg; + 3328 912 : struct snapraid_content* content = context->content; 3329 : STREAM* f; 3330 : char tmp[PATH_MAX]; 3331 : unsigned char buf[4]; 3332 : uint32_t crc_stored; 3333 : uint32_t crc_computed; 3334 : - 3335 908 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); + 3335 912 : pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); 3336 : 3337 913 : f = sopen_read(tmp); 3338 913 : if (f == 0) { @@ -3631,15 +3631,15 @@ 3569 12 : msg_progress("Scanning disk %s...\n", disk->name); 3570 : 3571 : /* for each file */ - 3572 133845 : for (j = tommy_list_head(&disk->filelist); j != 0; j = j->next) { - 3573 133791 : struct snapraid_file* file = j->data; + 3572 133854 : for (j = tommy_list_head(&disk->filelist); j != 0; j = j->next) { + 3573 133800 : struct snapraid_file* file = j->data; 3574 : - 3575 133791 : if (filter_path(filterlist_disk, 0, disk->name, file->sub) != 0 - 3576 80918 : || filter_path(filterlist_file, 0, disk->name, file->sub) != 0 - 3577 78085 : || filter_existence(filter_missing, disk->dir, file->sub) != 0 - 3578 38803 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0 + 3575 133800 : if (filter_path(filterlist_disk, 0, disk->name, file->sub) != 0 + 3576 80924 : || filter_path(filterlist_file, 0, disk->name, file->sub) != 0 + 3577 78090 : || filter_existence(filter_missing, disk->dir, file->sub) != 0 + 3578 38806 : || filter_correctness(filter_error, &state->infoarr, disk, file) != 0 3579 : ) { - 3580 109060 : file_flag_set(file, FILE_IS_EXCLUDED); + 3580 109102 : file_flag_set(file, FILE_IS_EXCLUDED); 3581 : } 3582 : } 3583 : @@ -3776,21 +3776,21 @@ 3714 : 3715 : #define PROGRESS_CLEAR " " 3716 : - 3717 1038828 : int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize) + 3717 1038958 : int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize) 3718 : { 3719 : time_t now; 3720 : int pred; 3721 : - 3722 1038828 : now = time(0); + 3722 1038958 : now = time(0); 3723 : 3724 : /* previous position */ - 3725 1038828 : pred = state->progress_ptr + PROGRESS_MAX - 1; - 3726 1038828 : if (pred >= PROGRESS_MAX) - 3727 1038640 : pred -= PROGRESS_MAX; + 3725 1038958 : pred = state->progress_ptr + PROGRESS_MAX - 1; + 3726 1038958 : if (pred >= PROGRESS_MAX) + 3727 1038770 : pred -= PROGRESS_MAX; 3728 : 3729 : /* if the previous measure is different */ - 3730 1038828 : if (state->progress_tick == 0 - 3731 1038640 : || state->progress_time[pred] != now + 3730 1038958 : if (state->progress_tick == 0 + 3731 1038770 : || state->progress_time[pred] != now 3732 : ) { 3733 : uint64_t tick_total; 3734 : uint64_t tick_cpu; @@ -3852,7 +3852,7 @@ 3790 : 3791 : /* estimate the cpu usage percentage */ 3792 72 : if (delta_tick_total != 0) - 3793 12 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total); + 3793 10 : out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total); 3794 : 3795 : /* estimate the remaining time in minutes */ 3796 72 : if (delta_pos != 0) @@ -3865,11 +3865,11 @@ 3803 : } else { 3804 253 : msg_bar("%u%%, %u MiB", out_perc, (unsigned)(countsize / MEGA)); 3805 253 : if (out_speed) - 3806 61 : msg_bar(", %u MiB/s", out_speed); + 3806 63 : msg_bar(", %u MiB/s", out_speed); 3807 253 : if (out_cpu) - 3808 12 : msg_bar(", CPU %u%%", out_cpu); + 3808 10 : msg_bar(", CPU %u%%", out_cpu); 3809 253 : if (out_eta) - 3810 2 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60); + 3810 0 : msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60); 3811 253 : msg_bar("%s\r", PROGRESS_CLEAR); 3812 253 : msg_flush(); 3813 : } @@ -3891,7 +3891,7 @@ 3829 : } 3830 : 3831 : /* stop if requested */ - 3832 1038828 : if (global_interrupt) { + 3832 1038958 : if (global_interrupt) { 3833 : /* LCOV_EXCL_START */ 3834 : if (!state->opt.gui) { 3835 : log_fatal("\n"); @@ -3903,7 +3903,7 @@ 3841 : /* LCOV_EXCL_STOP */ 3842 : } 3843 : - 3844 1038828 : return 0; + 3844 1038958 : return 0; 3845 : } 3846 : 3847 81 : void state_usage_print(struct snapraid_state* state) @@ -3919,7 +3919,7 @@ 3857 484 : struct snapraid_disk* disk = i->data; 3858 484 : tick_total += disk->tick; 3859 484 : if (disk->tick > tick_max) - 3860 100 : tick_max = disk->tick; + 3860 99 : tick_max = disk->tick; 3861 : } 3862 552 : for (l = 0; l < state->level; ++l) { 3863 471 : tick_total += state->parity[l].tick; diff --git a/cov/cmdline/state.h.func-sort-c.html b/cov/cmdline/state.h.func-sort-c.html index b1b14f40..05fa4cc0 100644 --- a/cov/cmdline/state.h.func-sort-c.html +++ b/cov/cmdline/state.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -61,15 +61,15 @@ state_usage_cpu - 771844 + 772778 state_usage_parity - 652636 + 653350 state_usage_disk - 621730 + 622545 state_usage_waste diff --git a/cov/cmdline/state.h.func.html b/cov/cmdline/state.h.func.html index 5ef1afff..37c5849d 100644 --- a/cov/cmdline/state.h.func.html +++ b/cov/cmdline/state.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -61,15 +61,15 @@ state_usage_cpu - 771844 + 772778 state_usage_disk - 621730 + 622545 state_usage_parity - 652636 + 653350 state_usage_waste diff --git a/cov/cmdline/state.h.gcov.html b/cov/cmdline/state.h.gcov.html index b420bafb..0cdf4d7f 100644 --- a/cov/cmdline/state.h.gcov.html +++ b/cov/cmdline/state.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -394,48 +394,48 @@ 332 : /** 333 : * Set the usage time for CPU. 334 : */ - 335 771844 : static inline void state_usage_cpu(struct snapraid_state* state) + 335 772778 : static inline void state_usage_cpu(struct snapraid_state* state) 336 : { - 337 771844 : uint64_t now = tick(); - 338 771844 : uint64_t delta = now - state->tick_last; + 337 772778 : uint64_t now = tick(); + 338 772778 : uint64_t delta = now - state->tick_last; 339 : 340 : /* increment the time spent in computations */ - 341 771844 : state->tick_cpu += delta; + 341 772778 : state->tick_cpu += delta; 342 : - 343 771844 : state->tick_last = now; - 344 771844 : } + 343 772778 : state->tick_last = now; + 344 772778 : } 345 : 346 : /** 347 : * Set the usage time for data disk. 348 : */ - 349 621730 : static inline void state_usage_disk(struct snapraid_state* state, struct snapraid_disk* disk) + 349 622545 : static inline void state_usage_disk(struct snapraid_state* state, struct snapraid_disk* disk) 350 : { - 351 621730 : uint64_t now = tick(); - 352 621730 : uint64_t delta = now - state->tick_last; + 351 622545 : uint64_t now = tick(); + 352 622545 : uint64_t delta = now - state->tick_last; 353 : 354 : /* increment the time spent in the data disk */ - 355 621730 : disk->tick += delta; - 356 621730 : state->tick_io += delta; + 355 622545 : disk->tick += delta; + 356 622545 : state->tick_io += delta; 357 : - 358 621730 : state->tick_last = now; - 359 621730 : } + 358 622545 : state->tick_last = now; + 359 622545 : } 360 : 361 : /** 362 : * Set the usage time for parity disk. 363 : */ - 364 652636 : static inline void state_usage_parity(struct snapraid_state* state, unsigned level) + 364 653350 : static inline void state_usage_parity(struct snapraid_state* state, unsigned level) 365 : { - 366 652636 : uint64_t now = tick(); - 367 652636 : uint64_t delta = now - state->tick_last; + 366 653350 : uint64_t now = tick(); + 367 653350 : uint64_t delta = now - state->tick_last; 368 : - 369 652636 : assert(level < LEV_MAX); + 369 653350 : assert(level < LEV_MAX); 370 : 371 : /* increment the time spent in the parity disk */ - 372 652636 : state->parity[level].tick += delta; - 373 652636 : state->tick_io += delta; + 372 653350 : state->parity[level].tick += delta; + 373 653350 : state->tick_io += delta; 374 : - 375 652636 : state->tick_last = now; - 376 652636 : } + 375 653350 : state->tick_last = now; + 376 653350 : } 377 : 378 : /** 379 : * Print the stats of the usage time. diff --git a/cov/cmdline/status.c.func-sort-c.html b/cov/cmdline/status.c.func-sort-c.html index f2906c5b..3a3013e8 100644 --- a/cov/cmdline/status.c.func-sort-c.html +++ b/cov/cmdline/status.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/cmdline/status.c.func.html b/cov/cmdline/status.c.func.html index 3dbe2d34..fd04e329 100644 --- a/cov/cmdline/status.c.func.html +++ b/cov/cmdline/status.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/cmdline/status.c.gcov.html b/cov/cmdline/status.c.gcov.html index d11e227a..59c5f405 100644 --- a/cov/cmdline/status.c.gcov.html +++ b/cov/cmdline/status.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -195,14 +195,14 @@ 133 : 134 : /* for each file in the disk */ 135 84 : node = disk->filelist; - 136 95602 : while (node) { + 136 95610 : while (node) { 137 : struct snapraid_file* file; 138 : - 139 95434 : file = node->data; - 140 95434 : node = node->next; /* next node */ + 139 95442 : file = node->data; + 140 95442 : node = node->next; /* next node */ 141 : 142 : /* check fragmentation */ - 143 95434 : if (file->blockmax != 0) { + 143 95442 : if (file->blockmax != 0) { 144 : block_off_t prev_pos; 145 : block_off_t last_pos; 146 : int fragmented; @@ -234,11 +234,11 @@ 172 : } 173 : 174 : /* count files */ - 175 95434 : ++file_count; - 176 95434 : ++disk_file_count; - 177 95434 : file_size += file->size; - 178 95434 : file_block_count += file->blockmax; - 179 95434 : disk_file_size += file->size; + 175 95442 : ++file_count; + 176 95442 : ++disk_file_count; + 177 95442 : file_size += file->size; + 178 95442 : file_block_count += file->blockmax; + 179 95442 : disk_file_size += file->size; 180 : } 181 : 182 84 : if (disk->free_blocks != 0) @@ -367,10 +367,10 @@ 305 : time_t scrub_time; 306 : 307 39606 : if (info_get_bad(info)) { - 308 1803 : if (bad == 0) + 308 1802 : if (bad == 0) 309 2 : bad_first = i; - 310 1803 : bad_last = i; - 311 1803 : ++bad; + 310 1802 : bad_last = i; + 311 1802 : ++bad; 312 : } 313 : 314 39606 : if (info_get_rehash(info)) @@ -379,10 +379,10 @@ 317 39606 : scrub_time = info_get_time(info); 318 : 319 39606 : if (info_get_justsynced(info)) { - 320 20357 : ++unscrubbed_blocks; + 320 20364 : ++unscrubbed_blocks; 321 : 322 : /* mark the time as not scrubbed */ - 323 20357 : scrub_time |= TIME_NEW; + 323 20364 : scrub_time |= TIME_NEW; 324 : } 325 : 326 39606 : timemap[count++] = scrub_time; @@ -414,16 +414,16 @@ 352 : /* output the info map */ 353 8 : i = 0; 354 8 : log_tag("info_count:%u\n", count); - 355 39 : while (i < count) { - 356 23 : unsigned j = i + 1; - 357 39629 : while (j < count && timemap[i] == timemap[j]) - 358 39583 : ++j; - 359 23 : if ((timemap[i] & TIME_NEW) == 0) { - 360 8 : log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i); + 355 41 : while (i < count) { + 356 25 : unsigned j = i + 1; + 357 39631 : while (j < count && timemap[i] == timemap[j]) + 358 39581 : ++j; + 359 25 : if ((timemap[i] & TIME_NEW) == 0) { + 360 9 : log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i); 361 : } else { - 362 15 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i); + 362 16 : log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i); 363 : } - 364 23 : i = j; + 364 25 : i = j; 365 : } 366 : 367 8 : oldest = timemap[0]; @@ -446,9 +446,9 @@ 384 560 : step_new = 0; 385 40726 : while (barpos < count && timemap[barpos] <= limit) { 386 39606 : if ((timemap[barpos] & TIME_NEW) != 0) - 387 20357 : ++step_new; + 387 20364 : ++step_new; 388 : else - 389 19249 : ++step_scrubbed; + 389 19242 : ++step_scrubbed; 390 39606 : ++barpos; 391 : } 392 : @@ -483,13 +483,13 @@ 421 : else 422 94 : printf("o"); 423 8232 : } else if (both > pivot_lower) { - 424 23 : if (scrubbed == both) - 425 8 : printf("*"); + 424 25 : if (scrubbed == both) + 425 9 : printf("*"); 426 : else - 427 15 : printf("o"); + 427 16 : printf("o"); 428 : } else { - 429 8209 : if (y == GRAPH_ROW - 1) - 430 537 : printf("_"); + 429 8207 : if (y == GRAPH_ROW - 1) + 430 535 : printf("_"); 431 : else 432 7672 : printf(" "); 433 : } @@ -536,19 +536,19 @@ 474 : 475 : /* print some of the errors */ 476 2 : bad_print = 0; - 477 611 : for (i = 0; i < blockmax; ++i) { - 478 611 : snapraid_info info = info_get(&state->infoarr, i); + 477 609 : for (i = 0; i < blockmax; ++i) { + 478 609 : snapraid_info info = info_get(&state->infoarr, i); 479 : 480 : /* skip unused blocks */ - 481 611 : if (info == 0) + 481 609 : if (info == 0) 482 0 : continue; 483 : - 484 611 : if (info_get_bad(info)) { + 484 609 : if (info_get_bad(info)) { 485 202 : printf(" %u", i); 486 202 : ++bad_print; 487 : } 488 : - 489 611 : if (bad_print > 100) { + 489 609 : if (bad_print > 100) { 490 2 : printf(" and %u more...", bad - bad_print); 491 2 : break; 492 : } diff --git a/cov/cmdline/stream.c.func-sort-c.html b/cov/cmdline/stream.c.func-sort-c.html index 1ad1bd38..929397e4 100644 --- a/cov/cmdline/stream.c.func-sort-c.html +++ b/cov/cmdline/stream.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 28 @@ -61,47 +61,47 @@ swrite - 130046569 + 129597634 sputb32 - 62124806 + 62339359 sputb64 - 34119322 + 34173479 sgetb32 - 18698507 + 18710390 sread - 12343180 + 12342909 sputbs - 12250827 + 12306366 sgetb64 - 10465700 + 10465937 sgetbs - 3732711 + 3732790 sfill - 606448 + 606496 sgetc_uncached - 298580 + 298585 sflush - 52551 + 52590 sgettok @@ -117,7 +117,7 @@ sclose - 2576 + 2575 scrc @@ -125,7 +125,7 @@ sopen_read - 1700 + 1701 sdeplete @@ -139,22 +139,22 @@ scrc_stream 929 - - sopen_multi_write - 929 - sputble32 929 - ssync - 913 + sopen_multi_write + 928 sopen_write 913 + + ssync + 912 + sgetble32 362 diff --git a/cov/cmdline/stream.c.func.html b/cov/cmdline/stream.c.func.html index 090c471f..518a0543 100644 --- a/cov/cmdline/stream.c.func.html +++ b/cov/cmdline/stream.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 28 @@ -61,7 +61,7 @@ sclose - 2576 + 2575 scrc @@ -77,19 +77,19 @@ sfill - 606448 + 606496 sflush - 52551 + 52590 sgetb32 - 18698507 + 18710390 sgetb64 - 10465700 + 10465937 sgetble32 @@ -97,11 +97,11 @@ sgetbs - 3732711 + 3732790 sgetc_uncached - 298580 + 298585 sgetlasttok @@ -129,11 +129,11 @@ sopen_multi_write - 929 + 928 sopen_read - 1700 + 1701 sopen_write @@ -141,11 +141,11 @@ sputb32 - 62124806 + 62339359 sputb64 - 34119322 + 34173479 sputble32 @@ -153,15 +153,15 @@ sputbs - 12250827 + 12306366 sread - 12343180 + 12342909 ssync - 913 + 912 stell @@ -169,7 +169,7 @@ swrite - 130046569 + 129597634
diff --git a/cov/cmdline/stream.c.gcov.html b/cov/cmdline/stream.c.gcov.html index 4cf237fc..93ec3984 100644 --- a/cov/cmdline/stream.c.gcov.html +++ b/cov/cmdline/stream.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 28 @@ -88,19 +88,19 @@ 26 : 27 : unsigned STREAM_SIZE = 1024 * 64; 28 : - 29 1700 : STREAM* sopen_read(const char* file) + 29 1701 : STREAM* sopen_read(const char* file) 30 : { 31 : #if HAVE_POSIX_FADVISE 32 : int ret; 33 : #endif - 34 1700 : STREAM* s = malloc_nofail(sizeof(STREAM)); + 34 1701 : STREAM* s = malloc_nofail(sizeof(STREAM)); 35 : 36 1701 : s->handle_size = 1; 37 1701 : s->handle = malloc_nofail(sizeof(struct stream_handle)); 38 : 39 1700 : pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file); 40 1701 : s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL); - 41 1701 : if (s->handle[0].f == -1) { + 41 1700 : if (s->handle[0].f == -1) { 42 50 : free(s->handle); 43 50 : free(s); 44 50 : return 0; @@ -108,8 +108,8 @@ 46 : 47 : #if HAVE_POSIX_FADVISE 48 : /* advise sequential access */ - 49 1651 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL); - 50 1651 : if (ret != 0) { + 49 1650 : ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL); + 50 1644 : if (ret != 0) { 51 : /* LCOV_EXCL_START */ 52 : close(s->handle[0].f); 53 : free(s->handle); @@ -119,33 +119,33 @@ 57 : } 58 : #endif 59 : - 60 1651 : s->buffer = malloc_nofail_test(STREAM_SIZE); - 61 1651 : s->pos = s->buffer; - 62 1651 : s->end = s->buffer; - 63 1651 : s->state = STREAM_STATE_READ; - 64 1651 : s->state_index = 0; - 65 1651 : s->offset = 0; - 66 1651 : s->offset_uncached = 0; - 67 1651 : s->crc = 0; - 68 1651 : s->crc_uncached = 0; - 69 1651 : s->crc_stream = CRC_IV; + 60 1644 : s->buffer = malloc_nofail_test(STREAM_SIZE); + 61 1650 : s->pos = s->buffer; + 62 1650 : s->end = s->buffer; + 63 1650 : s->state = STREAM_STATE_READ; + 64 1650 : s->state_index = 0; + 65 1650 : s->offset = 0; + 66 1650 : s->offset_uncached = 0; + 67 1650 : s->crc = 0; + 68 1650 : s->crc_uncached = 0; + 69 1650 : s->crc_stream = CRC_IV; 70 : - 71 1651 : return s; + 71 1650 : return s; 72 : } 73 : - 74 929 : STREAM* sopen_multi_write(unsigned count) + 74 928 : STREAM* sopen_multi_write(unsigned count) 75 : { 76 : unsigned i; 77 : - 78 929 : STREAM* s = malloc_nofail(sizeof(STREAM)); + 78 928 : STREAM* s = malloc_nofail(sizeof(STREAM)); 79 : 80 929 : s->handle_size = count; 81 929 : s->handle = malloc_nofail(count * sizeof(struct stream_handle)); 82 : - 83 1970 : for (i = 0; i < count; ++i) - 84 1041 : s->handle[i].f = -1; + 83 1968 : for (i = 0; i < count; ++i) + 84 1040 : s->handle[i].f = -1; 85 : - 86 929 : s->buffer = malloc_nofail_test(STREAM_SIZE); + 86 928 : s->buffer = malloc_nofail_test(STREAM_SIZE); 87 929 : s->pos = s->buffer; 88 929 : s->end = s->buffer + STREAM_SIZE; 89 929 : s->state = STREAM_STATE_WRITE; @@ -203,21 +203,21 @@ 141 913 : return s; 142 : } 143 : - 144 2576 : int sclose(STREAM* s) + 144 2575 : int sclose(STREAM* s) 145 : { - 146 2576 : int fail = 0; + 146 2575 : int fail = 0; 147 : unsigned i; 148 : - 149 2576 : if (s->state == STREAM_STATE_WRITE) { - 150 928 : if (sflush(s) != 0) { + 149 2575 : if (s->state == STREAM_STATE_WRITE) { + 150 927 : if (sflush(s) != 0) { 151 : /* LCOV_EXCL_START */ 152 : fail = 1; 153 : /* LCOV_EXCL_STOP */ 154 : } 155 : } 156 : - 157 5267 : for (i = 0; i < s->handle_size; ++i) { - 158 2689 : if (close(s->handle[i].f) != 0) { + 157 5266 : for (i = 0; i < s->handle_size; ++i) { + 158 2688 : if (close(s->handle[i].f) != 0) { 159 : /* LCOV_EXCL_START */ 160 : fail = 1; 161 : /* LCOV_EXCL_STOP */ @@ -252,41 +252,41 @@ 190 : * Fill the read stream buffer. 191 : * \return 0 if at least on char is read, or EOF on error. 192 : */ - 193 606448 : static int sfill(STREAM* s) + 193 606496 : static int sfill(STREAM* s) 194 : { 195 : ssize_t ret; 196 : - 197 606448 : if (s->state != STREAM_STATE_READ) { + 197 606496 : if (s->state != STREAM_STATE_READ) { 198 : /* LCOV_EXCL_START */ 199 : return EOF; 200 : /* LCOV_EXCL_STOP */ 201 : } 202 : - 203 605464 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE); + 203 605512 : ret = read(s->handle[0].f, s->buffer, STREAM_SIZE); 204 : - 205 605464 : if (ret < 0) { + 205 605512 : if (ret < 0) { 206 : /* LCOV_EXCL_START */ 207 : s->state = STREAM_STATE_ERROR; 208 : return EOF; 209 : /* LCOV_EXCL_STOP */ 210 : } - 211 605464 : if (ret == 0) { + 211 605512 : if (ret == 0) { 212 1522 : s->state = STREAM_STATE_EOF; 213 1522 : return EOF; 214 : } 215 : 216 : /* update the crc */ - 217 603942 : s->crc_uncached = s->crc; - 218 603942 : s->crc = crc32c(s->crc, s->buffer, ret); + 217 603990 : s->crc_uncached = s->crc; + 218 603990 : s->crc = crc32c(s->crc, s->buffer, ret); 219 : 220 : /* update the offset */ - 221 603942 : s->offset_uncached = s->offset; - 222 603942 : s->offset += ret; + 221 603990 : s->offset_uncached = s->offset; + 222 603990 : s->offset += ret; 223 : - 224 603942 : s->pos = s->buffer; - 225 603942 : s->end = s->buffer + ret; + 224 603990 : s->pos = s->buffer; + 225 603990 : s->end = s->buffer + ret; 226 : - 227 603942 : return 0; + 227 603990 : return 0; 228 : } 229 : 230 1042 : int sdeplete(STREAM* s, unsigned char* last) @@ -299,19 +299,19 @@ 237 : 238 : while (1) { 239 : /* increase the position up to 4 bytes before the end */ - 240 307868 : if (s->pos + 4 <= s->end) - 241 148091 : s->pos = s->end - 4; + 240 307911 : if (s->pos + 4 <= s->end) + 241 148134 : s->pos = s->end - 4; 242 : 243 : /* insert the last 4 bytes */ - 244 1467868 : while (s->pos < s->end) { - 245 852132 : last[0] = last[1]; - 246 852132 : last[1] = last[2]; - 247 852132 : last[2] = last[3]; - 248 852132 : last[3] = *s->pos++; + 244 1468126 : while (s->pos < s->end) { + 245 852304 : last[0] = last[1]; + 246 852304 : last[1] = last[2]; + 247 852304 : last[2] = last[3]; + 248 852304 : last[3] = *s->pos++; 249 : } 250 : 251 : /* fill again the buffer until the end of the file */ - 252 307868 : if (sfill(s) != 0) { + 252 307911 : if (sfill(s) != 0) { 253 : /* on error fail */ 254 1042 : if (serror(s)) { 255 : /* LCOV_EXCL_START */ @@ -322,31 +322,31 @@ 260 : /* on EOF terminate */ 261 1042 : break; 262 : } - 263 306826 : } + 263 306869 : } 264 : 265 1042 : return 0; 266 : } 267 : - 268 52551 : int sflush(STREAM* s) + 268 52590 : int sflush(STREAM* s) 269 : { 270 : ssize_t ret; 271 : ssize_t size; 272 : unsigned i; 273 : - 274 52551 : if (s->state != STREAM_STATE_WRITE) { + 274 52590 : if (s->state != STREAM_STATE_WRITE) { 275 : /* LCOV_EXCL_START */ 276 : return EOF; 277 : /* LCOV_EXCL_STOP */ 278 : } 279 : - 280 52551 : size = s->pos - s->buffer; - 281 52551 : if (!size) - 282 913 : return 0; + 280 52590 : size = s->pos - s->buffer; + 281 52590 : if (!size) + 282 909 : return 0; 283 : - 284 359365 : for (i = 0; i < s->handle_size; ++i) { - 285 307726 : ret = write(s->handle[i].f, s->buffer, size); + 284 359449 : for (i = 0; i < s->handle_size; ++i) { + 285 307768 : ret = write(s->handle[i].f, s->buffer, size); 286 : - 287 307727 : if (ret != size) { + 287 307768 : if (ret != size) { 288 : /* LCOV_EXCL_START */ 289 : s->state = STREAM_STATE_ERROR; 290 : s->state_index = i; @@ -362,16 +362,16 @@ 300 : * to be able to detect memory errors on the buffer, 301 : * happening during the write. 302 : */ - 303 51639 : s->crc = crc32c(s->crc, s->buffer, size); - 304 51639 : s->crc_uncached = s->crc; + 303 51681 : s->crc = crc32c(s->crc, s->buffer, size); + 304 51680 : s->crc_uncached = s->crc; 305 : 306 : /* update the offset */ - 307 51639 : s->offset += size; - 308 51639 : s->offset_uncached = s->offset; + 307 51680 : s->offset += size; + 308 51680 : s->offset_uncached = s->offset; 309 : - 310 51639 : s->pos = s->buffer; + 310 51680 : s->pos = s->buffer; 311 : - 312 51639 : return 0; + 312 51680 : return 0; 313 : } 314 : 315 1 : int64_t stell(STREAM* s) @@ -389,12 +389,12 @@ 327 929 : return s->crc_stream ^ CRC_IV; 328 : } 329 : - 330 298580 : int sgetc_uncached(STREAM* s) + 330 298585 : int sgetc_uncached(STREAM* s) 331 : { 332 : /* if at the end of the buffer, fill it */ - 333 298580 : if (s->pos == s->end && sfill(s) != 0) + 333 298585 : if (s->pos == s->end && sfill(s) != 0) 334 1464 : return EOF; - 335 297116 : return *s->pos++; + 335 297121 : return *s->pos++; 336 : } 337 : 338 7623 : int sgettok(STREAM* f, char* str, int size) @@ -434,35 +434,35 @@ 372 7623 : return i - str; 373 : } 374 : - 375 12343180 : int sread(STREAM* f, void* void_data, unsigned size) + 375 12342909 : int sread(STREAM* f, void* void_data, unsigned size) 376 : { - 377 12343180 : unsigned char* data = void_data; + 377 12342909 : unsigned char* data = void_data; 378 : 379 : /* if there is enough space in memory */ - 380 12343180 : if (sptrlookup(f, size)) { + 380 12342909 : if (sptrlookup(f, size)) { 381 : /* optimized version with all the data in memory */ - 382 12317138 : unsigned char* pos = sptrget(f); + 382 12316849 : unsigned char* pos = sptrget(f); 383 : 384 : /* copy it */ - 385 209705167 : while (size--) - 386 185070891 : *data++ = *pos++; + 385 209697747 : while (size--) + 386 185064049 : *data++ = *pos++; 387 : - 388 12317138 : sptrset(f, pos); + 388 12316849 : sptrset(f, pos); 389 : } else { 390 : /* standard version using sgetc() */ - 391 1373473 : while (size--) { - 392 1321389 : int c = sgetc(f); - 393 1321389 : if (c == EOF) { + 391 1373859 : while (size--) { + 392 1321739 : int c = sgetc(f); + 393 1321739 : if (c == EOF) { 394 : /* LCOV_EXCL_START */ 395 : return -1; 396 : /* LCOV_EXCL_STOP */ 397 : } 398 : - 399 1321389 : *data++ = c; + 399 1321739 : *data++ = c; 400 : } 401 : } 402 : - 403 12343180 : return 0; + 403 12342909 : return 0; 404 : } 405 : 406 5069 : int sgetline(STREAM* f, char* str, int size) @@ -575,76 +575,76 @@ 513 : } 514 : } 515 : - 516 18698507 : int sgetb32(STREAM* f, uint32_t* value) + 516 18710390 : int sgetb32(STREAM* f, uint32_t* value) 517 : { 518 : uint32_t v; 519 : unsigned char b; 520 : unsigned char s; 521 : int c; 522 : - 523 18698507 : v = 0; - 524 18698507 : s = 0; + 523 18710390 : v = 0; + 524 18710390 : s = 0; 525 : loop: - 526 35035464 : c = sgetc(f); - 527 35035464 : if (c == EOF) { + 526 35314985 : c = sgetc(f); + 527 35314985 : if (c == EOF) { 528 : /* LCOV_EXCL_START */ 529 : return -1; 530 : /* LCOV_EXCL_STOP */ 531 : } 532 : - 533 35035464 : b = (unsigned char)c; - 534 35035464 : if ((b & 0x80) == 0) { - 535 16336957 : v |= (uint32_t)b << s; - 536 16336957 : s += 7; - 537 16336957 : if (s >= 32) { + 533 35314985 : b = (unsigned char)c; + 534 35314985 : if ((b & 0x80) == 0) { + 535 16604595 : v |= (uint32_t)b << s; + 536 16604595 : s += 7; + 537 16604595 : if (s >= 32) { 538 : /* LCOV_EXCL_START */ 539 : return -1; 540 : /* LCOV_EXCL_STOP */ 541 : } - 542 16336957 : goto loop; + 542 16604595 : goto loop; 543 : } 544 : - 545 18698507 : v |= (uint32_t)(b & 0x7f) << s; + 545 18710390 : v |= (uint32_t)(b & 0x7f) << s; 546 : - 547 18698507 : *value = v; + 547 18710390 : *value = v; 548 : - 549 18698507 : return 0; + 549 18710390 : return 0; 550 : } 551 : - 552 10465700 : int sgetb64(STREAM* f, uint64_t* value) + 552 10465937 : int sgetb64(STREAM* f, uint64_t* value) 553 : { 554 : uint64_t v; 555 : unsigned char b; 556 : unsigned char s; 557 : int c; 558 : - 559 10465700 : v = 0; - 560 10465700 : s = 0; + 559 10465937 : v = 0; + 560 10465937 : s = 0; 561 : loop: - 562 38270922 : c = sgetc(f); - 563 38270922 : if (c == EOF) { + 562 38271575 : c = sgetc(f); + 563 38271575 : if (c == EOF) { 564 : /* LCOV_EXCL_START */ 565 : return -1; 566 : /* LCOV_EXCL_STOP */ 567 : } 568 : - 569 38270922 : b = (unsigned char)c; - 570 38270922 : if ((b & 0x80) == 0) { - 571 27805222 : v |= (uint64_t)b << s; - 572 27805222 : s += 7; - 573 27805222 : if (s >= 64) { + 569 38271575 : b = (unsigned char)c; + 570 38271575 : if ((b & 0x80) == 0) { + 571 27805638 : v |= (uint64_t)b << s; + 572 27805638 : s += 7; + 573 27805638 : if (s >= 64) { 574 : /* LCOV_EXCL_START */ 575 : return -1; 576 : /* LCOV_EXCL_STOP */ 577 : } - 578 27805222 : goto loop; + 578 27805638 : goto loop; 579 : } 580 : - 581 10465700 : v |= (uint64_t)(b & 0x7f) << s; + 581 10465937 : v |= (uint64_t)(b & 0x7f) << s; 582 : - 583 10465700 : *value = v; + 583 10465937 : *value = v; 584 : - 585 10465700 : return 0; + 585 10465937 : return 0; 586 : } 587 : 588 362 : int sgetble32(STREAM* f, uint32_t* value) @@ -662,35 +662,35 @@ 600 362 : return 0; 601 : } 602 : - 603 3732711 : int sgetbs(STREAM* f, char* str, int size) + 603 3732790 : int sgetbs(STREAM* f, char* str, int size) 604 : { 605 : uint32_t len; 606 : - 607 3732711 : if (sgetb32(f, &len) < 0) { + 607 3732790 : if (sgetb32(f, &len) < 0) { 608 : /* LCOV_EXCL_START */ 609 : return -1; 610 : /* LCOV_EXCL_STOP */ 611 : } 612 : - 613 3732711 : if (len + 1 > (uint32_t)size) { + 613 3732790 : if (len + 1 > (uint32_t)size) { 614 : /* LCOV_EXCL_START */ 615 : return -1; 616 : /* LCOV_EXCL_STOP */ 617 : } 618 : - 619 3732711 : str[len] = 0; + 619 3732790 : str[len] = 0; 620 : - 621 3732711 : return sread(f, str, (int)len); + 621 3732790 : return sread(f, str, (int)len); 622 : } 623 : - 624 130046569 : int swrite(const void* void_data, unsigned size, STREAM* f) + 624 129597634 : int swrite(const void* void_data, unsigned size, STREAM* f) 625 : { - 626 130046569 : const unsigned char* data = void_data; + 626 129597634 : const unsigned char* data = void_data; 627 : 628 : /* if there is enough space in memory */ - 629 130046569 : if (sptrlookup(f, size)) { + 629 129597634 : if (sptrlookup(f, size)) { 630 : /* optimized version with all the data in memory */ - 631 127834006 : unsigned char* pos = sptrget(f); + 631 128366511 : unsigned char* pos = sptrget(f); 632 : 633 : /** 634 : * Update the crc *before* writing the data in the buffer @@ -699,17 +699,17 @@ 637 : * to be able to detect memory errors on the buffer, 638 : * happening before we write it on the file. 639 : */ - 640 129791160 : f->crc_stream = crc32c_plain(f->crc_stream, data, size); + 640 127220529 : f->crc_stream = crc32c_plain(f->crc_stream, data, size); 641 : 642 : /* copy it */ - 643 1011408978 : while (size--) - 644 752691158 : *pos++ = *data++; + 643 984312399 : while (size--) + 644 729779043 : *pos++ = *data++; 645 : - 646 129358910 : sptrset(f, pos); + 646 127266678 : sptrset(f, pos); 647 : } else { 648 : /* standard version using sputc() */ - 649 355086 : while (size--) { - 650 321067 : if (sputc(*data++, f) != 0) { + 649 352837 : while (size--) { + 650 318158 : if (sputc(*data++, f) != 0) { 651 : /* LCOV_EXCL_START */ 652 : return -1; 653 : /* LCOV_EXCL_STOP */ @@ -717,49 +717,49 @@ 655 : } 656 : } 657 : - 658 131892349 : return 0; + 658 129224881 : return 0; 659 : } 660 : - 661 62124806 : int sputb32(uint32_t value, STREAM* s) + 661 62339359 : int sputb32(uint32_t value, STREAM* s) 662 : { 663 : unsigned char b; 664 : unsigned char buf[16]; 665 : unsigned i; 666 : - 667 62124806 : i = 0; + 667 62339359 : i = 0; 668 : loop: - 669 115908253 : b = value & 0x7f; - 670 115908253 : value >>= 7; + 669 117525500 : b = value & 0x7f; + 670 117525500 : value >>= 7; 671 : - 672 115908253 : if (value) { - 673 53783447 : buf[i++] = b; - 674 53783447 : goto loop; + 672 117525500 : if (value) { + 673 55186141 : buf[i++] = b; + 674 55186141 : goto loop; 675 : } 676 : - 677 62124806 : buf[i++] = b | 0x80; + 677 62339359 : buf[i++] = b | 0x80; 678 : - 679 62124806 : return swrite(buf, i, s); + 679 62339359 : return swrite(buf, i, s); 680 : } 681 : - 682 34119322 : int sputb64(uint64_t value, STREAM* s) + 682 34173479 : int sputb64(uint64_t value, STREAM* s) 683 : { 684 : unsigned char b; 685 : unsigned char buf[16]; 686 : unsigned i; 687 : - 688 34119322 : i = 0; + 688 34173479 : i = 0; 689 : loop: - 690 124052999 : b = value & 0x7f; - 691 124052999 : value >>= 7; + 690 124705929 : b = value & 0x7f; + 691 124705929 : value >>= 7; 692 : - 693 124052999 : if (value) { - 694 89933677 : buf[i++] = b; - 695 89933677 : goto loop; + 693 124705929 : if (value) { + 694 90532450 : buf[i++] = b; + 695 90532450 : goto loop; 696 : } 697 : - 698 34119322 : buf[i++] = b | 0x80; + 698 34173479 : buf[i++] = b | 0x80; 699 : - 700 34119322 : return swrite(buf, i, s); + 700 34173479 : return swrite(buf, i, s); 701 : } 702 : 703 929 : int sputble32(uint32_t value, STREAM* s) @@ -774,25 +774,25 @@ 712 929 : return swrite(buf, 4, s); 713 : } 714 : - 715 12250827 : int sputbs(const char* str, STREAM* f) + 715 12306366 : int sputbs(const char* str, STREAM* f) 716 : { - 717 12250827 : size_t len = strlen(str); + 717 12306366 : size_t len = strlen(str); 718 : - 719 12250827 : if (sputb32(len, f) != 0) { + 719 12306366 : if (sputb32(len, f) != 0) { 720 : /* LCOV_EXCL_START */ 721 : return -1; 722 : /* LCOV_EXCL_STOP */ 723 : } 724 : - 725 12311369 : return swrite(str, len, f); + 725 12287997 : return swrite(str, len, f); 726 : } 727 : 728 : #if HAVE_FSYNC - 729 913 : int ssync(STREAM* s) + 729 912 : int ssync(STREAM* s) 730 : { 731 : unsigned i; 732 : - 733 1826 : for (i = 0; i < s->handle_size; ++i) { + 733 1824 : for (i = 0; i < s->handle_size; ++i) { 734 913 : if (fsync(s->handle[i].f) != 0) { 735 : /* LCOV_EXCL_START */ 736 : s->state = STREAM_STATE_ERROR; @@ -802,7 +802,7 @@ 740 : } 741 : } 742 : - 743 913 : return 0; + 743 911 : return 0; 744 : } 745 : #endif 746 : diff --git a/cov/cmdline/stream.h.func-sort-c.html b/cov/cmdline/stream.h.func-sort-c.html index 3ba676b2..6fd4d017 100644 --- a/cov/cmdline/stream.h.func-sort-c.html +++ b/cov/cmdline/stream.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -60,28 +60,28 @@ Hit count Sort by hit count - sptrget - 143442663 + sptrlookup + 140471390 - sptrlookup - 140856705 + sptrget + 140020205 sptrset - 139615572 + 138951723 sgetc - 81925866 + 82206359 serror - 24801447 + 24784868 sputc - 23657932 + 23611223 sungetc diff --git a/cov/cmdline/stream.h.func.html b/cov/cmdline/stream.h.func.html index 09494c2a..50565355 100644 --- a/cov/cmdline/stream.h.func.html +++ b/cov/cmdline/stream.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -65,7 +65,7 @@ serror - 24801447 + 24784868 serrorfile @@ -73,7 +73,7 @@ sgetc - 81925866 + 82206359 sgeteol @@ -85,19 +85,19 @@ sptrget - 143442663 + 140020205 sptrlookup - 140856705 + 140471390 sptrset - 139615572 + 138951723 sputc - 23657932 + 23611223 sungetc diff --git a/cov/cmdline/stream.h.gcov.html b/cov/cmdline/stream.h.gcov.html index 3809d597..04b9f268 100644 --- a/cov/cmdline/stream.h.gcov.html +++ b/cov/cmdline/stream.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -221,33 +221,33 @@ 159 : /** 160 : * Check if the buffer has enough data loaded. 161 : */ - 162 140856705 : static inline int sptrlookup(STREAM* s, int size) + 162 140471390 : static inline int sptrlookup(STREAM* s, int size) 163 : { - 164 140856705 : return s->pos + size <= s->end; + 164 140471390 : return s->pos + size <= s->end; 165 : } 166 : 167 : /** 168 : * Get the current stream ptr. 169 : */ - 170 143442663 : static inline unsigned char* sptrget(STREAM* s) + 170 140020205 : static inline unsigned char* sptrget(STREAM* s) 171 : { - 172 143442663 : return s->pos; + 172 140020205 : return s->pos; 173 : } 174 : 175 : /** 176 : * Set the current stream ptr. 177 : */ - 178 139615572 : static inline void sptrset(STREAM* s, unsigned char* ptr) + 178 138951723 : static inline void sptrset(STREAM* s, unsigned char* ptr) 179 : { - 180 139615572 : s->pos = ptr; - 181 139615572 : } + 180 138951723 : s->pos = ptr; + 181 138951723 : } 182 : 183 : /** 184 : * Check the error status. Like ferror(). 185 : */ - 186 24801447 : static inline int serror(STREAM* s) + 186 24784868 : static inline int serror(STREAM* s) 187 : { - 188 24801447 : return s->state == STREAM_STATE_ERROR; + 188 24784868 : return s->state == STREAM_STATE_ERROR; 189 : } 190 : 191 : /** @@ -291,11 +291,11 @@ 229 : /** 230 : * Read a char. Like fgetc(). 231 : */ - 232 81925866 : static inline int sgetc(STREAM* s) + 232 82206359 : static inline int sgetc(STREAM* s) 233 : { - 234 81925866 : if (tommy_unlikely(s->pos == s->end)) - 235 298580 : return sgetc_uncached(s); - 236 81627286 : return *s->pos++; + 234 82206359 : if (tommy_unlikely(s->pos == s->end)) + 235 298585 : return sgetc_uncached(s); + 236 81907774 : return *s->pos++; 237 : } 238 : 239 : /** @@ -407,10 +407,10 @@ 345 : * Write a char. Like fputc(). 346 : * Return 0 on success or -1 on error. 347 : */ - 348 23657932 : static inline int sputc(int c, STREAM* s) + 348 23611223 : static inline int sputc(int c, STREAM* s) 349 : { - 350 23657932 : if (s->pos == s->end) { - 351 49796 : if (sflush(s) != 0) + 350 23611223 : if (s->pos == s->end) { + 351 49838 : if (sflush(s) != 0) 352 0 : return -1; 353 : } 354 : @@ -421,11 +421,11 @@ 359 : * to be able to detect memory errors on the buffer, 360 : * happening before we write it on the file. 361 : */ - 362 23657933 : s->crc_stream = crc32c_plain_char(s->crc_stream, c); + 362 23611224 : s->crc_stream = crc32c_plain_char(s->crc_stream, c); 363 : - 364 23816691 : *s->pos++ = c; + 364 23809904 : *s->pos++ = c; 365 : - 366 23816691 : return 0; + 366 23809904 : return 0; 367 : } 368 : 369 : /** diff --git a/cov/cmdline/support.c.func-sort-c.html b/cov/cmdline/support.c.func-sort-c.html index 5f799715..e77ef92a 100644 --- a/cov/cmdline/support.c.func-sort-c.html +++ b/cov/cmdline/support.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 29 @@ -61,55 +61,55 @@ pathcmp - 50334016 + 50336221 pathprint - 50027975 + 50030363 malloc_nofail - 13871380 + 13871886 pathcpy - 6858280 + 6858601 strdup_nofail - 5662644 + 5663011 log_tag - 4043608 + 4041705 esc - 3594259 + 3592843 mkancestor - 793004 + 792978 log_error - 614821 + 614592 msg_info - 296170 + 295863 msg_verbose - 127078 + 126936 fmtime - 118002 + 117937 pathexport - 17567 + 17569 log_expected @@ -137,7 +137,7 @@ msg_bar - 954 + 952 log_fatal @@ -149,7 +149,7 @@ msg_status - 568 + 569 malloc_counter diff --git a/cov/cmdline/support.c.func.html b/cov/cmdline/support.c.func.html index efa7b572..65c60503 100644 --- a/cov/cmdline/support.c.func.html +++ b/cov/cmdline/support.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 29 @@ -65,15 +65,15 @@ esc - 3594259 + 3592843 fmtime - 118002 + 117937 log_error - 614821 + 614592 log_expected @@ -89,7 +89,7 @@ log_tag - 4043608 + 4041705 malloc_counter @@ -97,15 +97,15 @@ malloc_nofail - 13871380 + 13871886 mkancestor - 793004 + 792978 msg_bar - 954 + 952 msg_flush @@ -113,7 +113,7 @@ msg_info - 296170 + 295863 msg_progress @@ -121,11 +121,11 @@ msg_status - 568 + 569 msg_verbose - 127078 + 126936 pathcat @@ -137,11 +137,11 @@ pathcmp - 50334016 + 50336221 pathcpy - 6858280 + 6858601 pathcut @@ -149,7 +149,7 @@ pathexport - 17567 + 17569 pathimport @@ -157,7 +157,7 @@ pathprint - 50027975 + 50030363 pathslash @@ -181,7 +181,7 @@ strdup_nofail - 5662644 + 5663011
diff --git a/cov/cmdline/support.c.gcov.html b/cov/cmdline/support.c.gcov.html index c725286a..07fccc29 100644 --- a/cov/cmdline/support.c.gcov.html +++ b/cov/cmdline/support.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 29 @@ -138,27 +138,27 @@ 76 804 : pthread_mutex_unlock(&msg_lock); 77 804 : } 78 : - 79 614821 : void log_error(const char* format, ...) + 79 614592 : void log_error(const char* format, ...) 80 : { 81 : va_list ap; 82 : - 83 614821 : pthread_mutex_lock(&msg_lock); + 83 614592 : pthread_mutex_lock(&msg_lock); 84 : - 85 614821 : if (stdlog) { - 86 612910 : va_start(ap, format); - 87 612910 : fprintf(stdlog, "msg:error: "); - 88 612910 : vfprintf(stdlog, format, ap); - 89 612910 : fflush(stdlog); - 90 612910 : va_end(ap); + 85 614592 : if (stdlog) { + 86 612682 : va_start(ap, format); + 87 612682 : fprintf(stdlog, "msg:error: "); + 88 612682 : vfprintf(stdlog, format, ap); + 89 612682 : fflush(stdlog); + 90 612682 : va_end(ap); 91 : } else { - 92 1911 : va_start(ap, format); - 93 1911 : vfprintf(stderr, format, ap); - 94 1911 : fflush(stderr); - 95 1911 : va_end(ap); + 92 1910 : va_start(ap, format); + 93 1910 : vfprintf(stderr, format, ap); + 94 1910 : fflush(stderr); + 95 1910 : va_end(ap); 96 : } 97 : - 98 614821 : pthread_mutex_unlock(&msg_lock); - 99 614821 : } + 98 614592 : pthread_mutex_unlock(&msg_lock); + 99 614592 : } 100 : 101 11751 : void log_expected(const char* format, ...) 102 : { @@ -177,22 +177,22 @@ 115 11751 : pthread_mutex_unlock(&msg_lock); 116 11751 : } 117 : - 118 4043608 : void log_tag(const char* format, ...) + 118 4041705 : void log_tag(const char* format, ...) 119 : { 120 : va_list ap; 121 : - 122 4043608 : pthread_mutex_lock(&msg_lock); + 122 4041705 : pthread_mutex_lock(&msg_lock); 123 : - 124 4043608 : if (stdlog) { - 125 2964603 : va_start(ap, format); - 126 2964603 : vfprintf(stdlog, format, ap); + 124 4041705 : if (stdlog) { + 125 2962677 : va_start(ap, format); + 126 2962677 : vfprintf(stdlog, format, ap); 127 : /* here we intentionally don't flush */ 128 : /* to make the output faster */ - 129 2964603 : va_end(ap); + 129 2962677 : va_end(ap); 130 : } 131 : - 132 4043608 : pthread_mutex_unlock(&msg_lock); - 133 4043608 : } + 132 4041705 : pthread_mutex_unlock(&msg_lock); + 133 4041705 : } 134 : 135 1108 : void log_flush(void) 136 : { @@ -206,11 +206,11 @@ 144 1108 : pthread_mutex_unlock(&msg_lock); 145 1108 : } 146 : - 147 568 : void msg_status(const char* format, ...) + 147 569 : void msg_status(const char* format, ...) 148 : { 149 : va_list ap; 150 : - 151 568 : pthread_mutex_lock(&msg_lock); + 151 569 : pthread_mutex_lock(&msg_lock); 152 : 153 569 : if (stdlog) { 154 276 : va_start(ap, format); @@ -230,24 +230,24 @@ 168 569 : pthread_mutex_unlock(&msg_lock); 169 569 : } 170 : - 171 296170 : void msg_info(const char* format, ...) + 171 295863 : void msg_info(const char* format, ...) 172 : { 173 : va_list ap; 174 : - 175 296170 : pthread_mutex_lock(&msg_lock); + 175 295863 : pthread_mutex_lock(&msg_lock); 176 : 177 : /* don't output in stdlog as these messages */ 178 : /* are always paired with a msg_tag() call */ 179 : - 180 296170 : if (msg_level >= MSG_INFO) { - 181 28833 : va_start(ap, format); - 182 28833 : vfprintf(stdout, format, ap); - 183 28833 : fflush(stdout); - 184 28833 : va_end(ap); + 180 295863 : if (msg_level >= MSG_INFO) { + 181 28776 : va_start(ap, format); + 182 28776 : vfprintf(stdout, format, ap); + 183 28776 : fflush(stdout); + 184 28776 : va_end(ap); 185 : } 186 : - 187 296170 : pthread_mutex_unlock(&msg_lock); - 188 296170 : } + 187 295863 : pthread_mutex_unlock(&msg_lock); + 188 295863 : } 189 : 190 3911 : void msg_progress(const char* format, ...) 191 : { @@ -273,48 +273,48 @@ 211 3911 : pthread_mutex_unlock(&msg_lock); 212 3911 : } 213 : - 214 954 : void msg_bar(const char* format, ...) + 214 952 : void msg_bar(const char* format, ...) 215 : { 216 : va_list ap; 217 : - 218 954 : pthread_mutex_lock(&msg_lock); + 218 952 : pthread_mutex_lock(&msg_lock); 219 : 220 : /* don't output in stdlog as these messages */ 221 : /* are intended for screen only */ 222 : /* also don't flush stdout as they are intended to be partial messages */ 223 : - 224 954 : if (msg_level >= MSG_BAR) { + 224 952 : if (msg_level >= MSG_BAR) { 225 0 : va_start(ap, format); 226 0 : vfprintf(stdout, format, ap); 227 0 : va_end(ap); 228 : } 229 : - 230 954 : pthread_mutex_unlock(&msg_lock); - 231 954 : } + 230 952 : pthread_mutex_unlock(&msg_lock); + 231 952 : } 232 : - 233 127078 : void msg_verbose(const char* format, ...) + 233 126936 : void msg_verbose(const char* format, ...) 234 : { 235 : va_list ap; 236 : - 237 127078 : pthread_mutex_lock(&msg_lock); + 237 126936 : pthread_mutex_lock(&msg_lock); 238 : - 239 127078 : if (stdlog) { - 240 125434 : va_start(ap, format); - 241 125434 : fprintf(stdlog, "msg:verbose: "); - 242 125434 : vfprintf(stdlog, format, ap); - 243 125434 : fflush(stdlog); - 244 125434 : va_end(ap); + 239 126936 : if (stdlog) { + 240 125292 : va_start(ap, format); + 241 125292 : fprintf(stdlog, "msg:verbose: "); + 242 125292 : vfprintf(stdlog, format, ap); + 243 125292 : fflush(stdlog); + 244 125292 : va_end(ap); 245 : } 246 : - 247 127078 : if (msg_level >= MSG_VERBOSE) { + 247 126936 : if (msg_level >= MSG_VERBOSE) { 248 79 : va_start(ap, format); 249 79 : vfprintf(stdout, format, ap); 250 79 : fflush(stdout); 251 79 : va_end(ap); 252 : } 253 : - 254 127078 : pthread_mutex_unlock(&msg_lock); - 255 127078 : } + 254 126936 : pthread_mutex_unlock(&msg_lock); + 255 126936 : } 256 : 257 440 : void msg_flush(void) 258 : { @@ -351,20 +351,20 @@ 289 : *p++ = to; \ 290 : break 291 : - 292 3594259 : const char* esc(const char* str) + 292 3592843 : const char* esc(const char* str) 293 : { - 294 3594259 : char* begin = esc_table[esc_index]; - 295 3594259 : char* end = begin + PATH_MAX; - 296 3594259 : char* p = begin; + 294 3592843 : char* begin = esc_table[esc_index]; + 295 3592843 : char* end = begin + PATH_MAX; + 296 3592843 : char* p = begin; 297 : 298 : /* next call uses the next buffer */ - 299 3594259 : esc_index = (esc_index + 1) % ESC_MAX; + 299 3592843 : esc_index = (esc_index + 1) % ESC_MAX; 300 : 301 : /* copy string with escaping */ - 302 53734097 : while (*str) { - 303 46545579 : char c = *str; + 302 53695808 : while (*str) { + 303 46510122 : char c = *str; 304 : - 305 46545579 : switch (c) { + 305 46510122 : switch (c) { 306 : 307 0 : ESCAPE('\n', 'n'); 308 0 : ESCAPE('\r', 'r'); @@ -372,21 +372,21 @@ 310 0 : ESCAPE('\\', '\\'); 311 : 312 : default: - 313 46545579 : if (p == end) + 313 46510122 : if (p == end) 314 0 : goto bail; - 315 46545579 : *p++ = c; - 316 46545579 : break; + 315 46510122 : *p++ = c; + 316 46510122 : break; 317 : } 318 : - 319 46545579 : ++str; + 319 46510122 : ++str; 320 : } 321 : 322 : /* put final 0 */ - 323 3594259 : if (p == end) + 323 3592843 : if (p == end) 324 0 : goto bail; - 325 3594259 : *p = 0; + 325 3592843 : *p = 0; 326 : - 327 7188518 : return begin; + 327 7185686 : return begin; 328 : 329 : bail: 330 : /* LCOV_EXCL_START */ @@ -411,19 +411,19 @@ 349 : /****************************************************************************/ 350 : /* path */ 351 : - 352 6858280 : void pathcpy(char* dst, size_t size, const char* src) + 352 6858601 : void pathcpy(char* dst, size_t size, const char* src) 353 : { - 354 6858280 : size_t len = strlen(src); + 354 6858601 : size_t len = strlen(src); 355 : - 356 6858280 : if (len + 1 > size) { + 356 6858601 : if (len + 1 > size) { 357 : /* LCOV_EXCL_START */ 358 : log_fatal("Path too long\n"); 359 : exit(EXIT_FAILURE); 360 : /* LCOV_EXCL_STOP */ 361 : } 362 : - 363 6858280 : memcpy(dst, src, len + 1); - 364 6858280 : } + 363 6858601 : memcpy(dst, src, len + 1); + 364 6858601 : } 365 : 366 248 : void pathcat(char* dst, size_t size, const char* src) 367 : { @@ -469,9 +469,9 @@ 407 : #endif 408 8852 : } 409 : - 410 17567 : void pathexport(char* dst, size_t size, const char* src) + 410 17569 : void pathexport(char* dst, size_t size, const char* src) 411 : { - 412 17567 : pathcpy(dst, size, src); + 412 17569 : pathcpy(dst, size, src); 413 : 414 : #ifdef _WIN32 415 : /* convert all C '/' to Windows '\' */ @@ -481,24 +481,24 @@ 419 : ++dst; 420 : } 421 : #endif - 422 17567 : } + 422 17569 : } 423 : - 424 50027975 : void pathprint(char* dst, size_t size, const char* format, ...) + 424 50030363 : void pathprint(char* dst, size_t size, const char* format, ...) 425 : { 426 : size_t len; 427 : va_list ap; 428 : - 429 50027975 : va_start(ap, format); - 430 50027975 : len = vsnprintf(dst, size, format, ap); - 431 50027975 : va_end(ap); + 429 50030363 : va_start(ap, format); + 430 50030363 : len = vsnprintf(dst, size, format, ap); + 431 50030363 : va_end(ap); 432 : - 433 50027975 : if (len >= size) { + 433 50030363 : if (len >= size) { 434 : /* LCOV_EXCL_START */ 435 : log_fatal("Path too long\n"); 436 : exit(EXIT_FAILURE); 437 : /* LCOV_EXCL_STOP */ 438 : } - 439 50027975 : } + 439 50030363 : } 440 : 441 7319 : void pathslash(char* dst, size_t size) 442 : { @@ -526,7 +526,7 @@ 464 0 : dst[0] = 0; 465 30 : } 466 : - 467 50334016 : int pathcmp(const char* a, const char* b) + 467 50336221 : int pathcmp(const char* a, const char* b) 468 : { 469 : #ifdef _WIN32 470 : char ai[PATH_MAX]; @@ -539,32 +539,32 @@ 477 : /* case insensitive compare in Windows */ 478 : return stricmp(ai, bi); 479 : #else - 480 50334016 : return strcmp(a, b); + 480 50336221 : return strcmp(a, b); 481 : #endif 482 : } 483 : 484 : /****************************************************************************/ 485 : /* filesystem */ 486 : - 487 793004 : int mkancestor(const char* file) + 487 792978 : int mkancestor(const char* file) 488 : { 489 : char dir[PATH_MAX]; 490 : struct stat st; 491 : char* c; 492 : - 493 793004 : pathcpy(dir, sizeof(dir), file); + 493 792978 : pathcpy(dir, sizeof(dir), file); 494 : - 495 793004 : c = strrchr(dir, '/'); - 496 793004 : if (!c) { + 495 792978 : c = strrchr(dir, '/'); + 496 792978 : if (!c) { 497 : /* no ancestor */ 498 0 : return 0; 499 : } 500 : 501 : /* clear the file */ - 502 793004 : *c = 0; + 502 792978 : *c = 0; 503 : 504 : /* if it's the root dir */ - 505 793004 : if (*dir == 0) { + 505 792978 : if (*dir == 0) { 506 : /* nothing more to do */ 507 0 : return 0; 508 : } @@ -587,9 +587,9 @@ 525 : * Also in Windows it's better to use lstat() than stat() because it 526 : * doen't need to open the dir with CreateFile(). 527 : */ - 528 793004 : if (lstat(dir, &st) == 0) { + 528 792978 : if (lstat(dir, &st) == 0) { 529 : /* it already exists */ - 530 792924 : return 0; + 530 792898 : return 0; 531 : } 532 : 533 : /* recursively create them all */ @@ -610,7 +610,7 @@ 548 80 : return 0; 549 : } 550 : - 551 118002 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec) + 551 117937 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec) 552 : { 553 : #if HAVE_FUTIMENS 554 : struct timespec tv[2]; @@ -620,15 +620,15 @@ 558 : int ret; 559 : 560 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */ - 561 118002 : tv[0].tv_sec = mtime_sec; - 562 118002 : if (mtime_nsec != STAT_NSEC_INVALID) - 563 118002 : tv[0].tv_nsec = mtime_nsec; + 561 117937 : tv[0].tv_sec = mtime_sec; + 562 117937 : if (mtime_nsec != STAT_NSEC_INVALID) + 563 117937 : tv[0].tv_nsec = mtime_nsec; 564 : else 565 0 : tv[0].tv_nsec = 0; - 566 118002 : tv[1].tv_sec = tv[0].tv_sec; - 567 118002 : tv[1].tv_nsec = tv[0].tv_nsec; + 566 117937 : tv[1].tv_sec = tv[0].tv_sec; + 567 117937 : tv[1].tv_nsec = tv[0].tv_nsec; 568 : - 569 118002 : ret = futimens(f, tv); + 569 117937 : ret = futimens(f, tv); 570 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */ 571 : tv[0].tv_sec = mtime_sec; 572 : if (mtime_nsec != STAT_NSEC_INVALID) @@ -653,7 +653,7 @@ 591 : #error No function available to set file timestamps with sub-second precision 592 : #endif 593 : - 594 118002 : return ret; + 594 117937 : return ret; 595 : } 596 : 597 : /****************************************************************************/ @@ -718,11 +718,11 @@ 656 : } 657 : /* LCOV_EXCL_STOP */ 658 : - 659 13871380 : void* malloc_nofail(size_t size) + 659 13871886 : void* malloc_nofail(size_t size) 660 : { - 661 13871380 : void* ptr = malloc(size); + 661 13871886 : void* ptr = malloc(size); 662 : - 663 13871380 : if (!ptr) { + 663 13871886 : if (!ptr) { 664 : /* LCOV_EXCL_START */ 665 : malloc_fail(size); 666 : exit(EXIT_FAILURE); @@ -736,12 +736,12 @@ 674 : /* Filling the memory doesn't ensure to disable OOM, but it increase a lot the chances to */ 675 : /* get a real error from malloc() instead than a process killed. */ 676 : /* Note that calloc() doesn't have the same effect. */ - 677 13871380 : memset(ptr, 0xA5, size); + 677 13871886 : memset(ptr, 0xA5, size); 678 : #endif 679 : - 680 13871380 : mcounter += size; + 680 13871886 : mcounter += size; 681 : - 682 13871380 : return ptr; + 682 13871886 : return ptr; 683 : } 684 : 685 9283 : void* calloc_nofail(size_t count, size_t size) @@ -767,27 +767,27 @@ 705 9283 : return ptr; 706 : } 707 : - 708 5662644 : char* strdup_nofail(const char* str) + 708 5663011 : char* strdup_nofail(const char* str) 709 : { 710 : size_t size; 711 : char* ptr; 712 : - 713 5662644 : size = strlen(str) + 1; + 713 5663011 : size = strlen(str) + 1; 714 : - 715 5662644 : ptr = malloc(size); + 715 5663011 : ptr = malloc(size); 716 : - 717 5662644 : if (!ptr) { + 717 5663011 : if (!ptr) { 718 : /* LCOV_EXCL_START */ 719 : malloc_fail(size); 720 : exit(EXIT_FAILURE); 721 : /* LCOV_EXCL_STOP */ 722 : } 723 : - 724 5662644 : memcpy(ptr, str, size); + 724 5663011 : memcpy(ptr, str, size); 725 : - 726 5662644 : mcounter += size; + 726 5663011 : mcounter += size; 727 : - 728 5662644 : return ptr; + 728 5663011 : return ptr; 729 : } 730 : 731 : /****************************************************************************/ @@ -822,8 +822,8 @@ 760 : 761 : /* preclear attribute */ 762 25 : *serial = 0; - 763 6525 : for (i = 0; i < SMART_COUNT; ++i) - 764 6500 : smart[i] = SMART_UNASSIGNED; + 763 6501 : for (i = 0; i < SMART_COUNT; ++i) + 764 6476 : smart[i] = SMART_UNASSIGNED; 765 : 766 : /* read the file */ 767 25 : inside = 0; diff --git a/cov/cmdline/sync.c.func-sort-c.html b/cov/cmdline/sync.c.func-sort-c.html index cd8f26c6..f3bdcd37 100644 --- a/cov/cmdline/sync.c.func-sort-c.html +++ b/cov/cmdline/sync.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/cmdline/sync.c.func.html b/cov/cmdline/sync.c.func.html index 21f3a3b8..e5f48fb5 100644 --- a/cov/cmdline/sync.c.func.html +++ b/cov/cmdline/sync.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/cmdline/sync.c.gcov.html b/cov/cmdline/sync.c.gcov.html index 17d69be4..36ec1bda 100644 --- a/cov/cmdline/sync.c.gcov.html +++ b/cov/cmdline/sync.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -488,14 +488,14 @@ 426 4180078 : one_valid = 1; 427 : 428 4389366 : if (block_has_invalid_parity(block)) - 429 360958 : one_invalid = 1; + 429 361206 : one_invalid = 1; 430 : } 431 : 432 : /* if none valid or none invalid, we don't need to update */ 433 733118 : if (!one_invalid || !one_valid) - 434 568698 : return 0; + 434 568436 : return 0; 435 : - 436 164420 : return 1; + 436 164682 : return 1; 437 : } 438 : 439 68 : static int state_sync_process(struct snapraid_state* state, struct snapraid_parity_handle** parity, block_off_t blockstart, block_off_t blockmax) @@ -559,8 +559,8 @@ 497 68 : countmax = 0; 498 366627 : for (i = blockstart; i < blockmax; ++i) { 499 366559 : if (!block_is_enabled(i, handle, diskmax)) - 500 284349 : continue; - 501 82210 : ++countmax; + 500 284218 : continue; + 501 82341 : ++countmax; 502 : } 503 : 504 : /* compute the autosave size for all disk, even if not read */ @@ -589,26 +589,26 @@ 527 : int rehash; 528 : 529 366559 : if (!block_is_enabled(i, handle, diskmax)) - 530 284349 : continue; + 530 284218 : continue; 531 : 532 : /* one more block processed for autosave */ - 533 82210 : ++autosavedone; - 534 82210 : --autosavemissing; + 533 82341 : ++autosavedone; + 534 82341 : --autosavemissing; 535 : 536 : /* by default process the block, and skip it if something go wrong */ - 537 82210 : error_on_this_block = 0; - 538 82210 : silent_error_on_this_block = 0; - 539 82210 : io_error_on_this_block = 0; - 540 82210 : fixed_error_on_this_block = 0; + 537 82341 : error_on_this_block = 0; + 538 82341 : silent_error_on_this_block = 0; + 539 82341 : io_error_on_this_block = 0; + 540 82341 : fixed_error_on_this_block = 0; 541 : 542 : /* keep track of the number of failed blocks */ - 543 82210 : failed_count = 0; + 543 82341 : failed_count = 0; 544 : 545 : /* get block specific info */ - 546 82210 : info = info_get(&state->infoarr, i); + 546 82341 : info = info_get(&state->infoarr, i); 547 : 548 : /* if we have to use the old hash */ - 549 82210 : rehash = info_get_rehash(info); + 549 82341 : rehash = info_get_rehash(info); 550 : 551 : /* it could happens that all the blocks are EMPTY/BLK and CHG but with the hash */ 552 : /* still matching because the specific CHG block was not modified. */ @@ -616,55 +616,55 @@ 554 : /* have the hash cleared (::clear_past_hash flag), and then they won't never match the hash. */ 555 : /* We are treating only CHG blocks created at runtime. */ 556 : /* In such case, we can avoid to update parity, because it would be the same as before */ - 557 82210 : parity_needs_to_be_updated = 0; + 557 82341 : parity_needs_to_be_updated = 0; 558 : 559 : /* if the block is marked as bad, we force the parity update */ 560 : /* because the bad block may be the result of a wrong parity */ - 561 82210 : if (info_get_bad(info)) + 561 82341 : if (info_get_bad(info)) 562 0 : parity_needs_to_be_updated = 1; 563 : 564 : /* for each disk, process the block */ - 565 575470 : for (j = 0; j < diskmax; ++j) { + 565 576387 : for (j = 0; j < diskmax; ++j) { 566 : int read_size; 567 : unsigned char hash[HASH_SIZE]; 568 : struct snapraid_block* block; 569 : unsigned block_state; - 570 493260 : struct snapraid_disk* disk = handle[j].disk; + 570 494046 : struct snapraid_disk* disk = handle[j].disk; 571 : struct snapraid_file* file; 572 : block_off_t file_pos; 573 : 574 : /* by default no rehash in case of "continue" */ - 575 493260 : rehandle[j].block = 0; + 575 494046 : rehandle[j].block = 0; 576 : 577 : /* if the disk position is not used */ - 578 493260 : if (!disk) { + 578 494046 : if (!disk) { 579 : /* use an empty block */ 580 0 : memset(buffer[j], 0, state->block_size); - 581 89224 : continue; + 581 89194 : continue; 582 : } 583 : 584 : /* get the block */ - 585 493260 : block = fs_par2block_get(disk, i); + 585 494046 : block = fs_par2block_get(disk, i); 586 : 587 : /* get the state of the block */ - 588 493260 : block_state = block_state_get(block); + 588 494046 : block_state = block_state_get(block); 589 : 590 : /* if the block has invalid parity, */ 591 : /* we have to take care of it in case of recover */ - 592 493260 : if (block_has_invalid_parity(block)) { + 592 494046 : if (block_has_invalid_parity(block)) { 593 : /* store it in the failed set, because */ 594 : /* the parity may be still computed with the previous content */ - 595 180479 : failed[failed_count].index = j; - 596 180479 : failed[failed_count].size = state->block_size; - 597 180479 : failed[failed_count].block = block; - 598 180479 : ++failed_count; + 595 180603 : failed[failed_count].index = j; + 596 180603 : failed[failed_count].size = state->block_size; + 597 180603 : failed[failed_count].block = block; + 598 180603 : ++failed_count; 599 : 600 : /* if the block has invalid parity, we have to update the parity */ 601 : /* to include this block change */ 602 : /* This also apply to CHG blocks, but we are going to handle */ 603 : /* later this case to do the updates only if really needed */ - 604 180479 : if (block_state != BLOCK_STATE_CHG) - 605 56263 : parity_needs_to_be_updated = 1; + 604 180603 : if (block_state != BLOCK_STATE_CHG) + 605 56266 : parity_needs_to_be_updated = 1; 606 : 607 : /* note that DELETE blocks are skipped in the next check */ 608 : /* and we have to store them in the failed blocks */ @@ -675,24 +675,24 @@ 613 : 614 : /* if the block has no file, meanining that it's EMPTY or DELETED, */ 615 : /* it doesn't partecipate in the new parity computation */ - 616 493260 : if (!block_has_file(block)) { + 616 494046 : if (!block_has_file(block)) { 617 : /* use an empty block */ - 618 88322 : memset(buffer[j], 0, state->block_size); - 619 88322 : continue; + 618 88293 : memset(buffer[j], 0, state->block_size); + 619 88293 : continue; 620 : } 621 : 622 : /* get the file of this block */ - 623 404938 : file = fs_par2file_get(disk, i, &file_pos); + 623 405753 : file = fs_par2file_get(disk, i, &file_pos); 624 : 625 : /* until now is CPU */ - 626 404938 : state_usage_cpu(state); + 626 405753 : state_usage_cpu(state); 627 : 628 : /* if the file is different than the current one, close it */ - 629 404938 : if (handle[j].file != 0 && handle[j].file != file) { + 629 405753 : if (handle[j].file != 0 && handle[j].file != file) { 630 : /* keep a pointer at the file we are going to close for error reporting */ - 631 168338 : struct snapraid_file* report = handle[j].file; - 632 168338 : ret = handle_close(&handle[j]); - 633 168338 : if (ret == -1) { + 631 168779 : struct snapraid_file* report = handle[j].file; + 632 168779 : ret = handle_close(&handle[j]); + 633 168779 : if (ret == -1) { 634 : /* LCOV_EXCL_START */ 635 : /* This one is really an unexpected error, because we are only reading */ 636 : /* and closing a descriptor should never fail */ @@ -715,8 +715,8 @@ 653 : } 654 : } 655 : - 656 404938 : ret = handle_open(&handle[j], file, state->file_mode, log_error, 0); - 657 404938 : if (ret == -1) { + 656 405753 : ret = handle_open(&handle[j], file, state->file_mode, log_error, 0); + 657 405753 : if (ret == -1) { 658 12 : if (errno == EIO) { 659 : /* LCOV_EXCL_START */ 660 : log_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); @@ -762,10 +762,10 @@ 700 : } 701 : 702 : /* check if the file is changed */ - 703 404926 : if (handle[j].st.st_size != file->size - 704 404924 : || handle[j].st.st_mtime != file->mtime_sec - 705 404922 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec - 706 404922 : || handle[j].st.st_ino != file->inode + 703 405741 : if (handle[j].st.st_size != file->size + 704 405739 : || handle[j].st.st_mtime != file->mtime_sec + 705 405737 : || STAT_NSEC(&handle[j].st) != file->mtime_nsec + 706 405737 : || handle[j].st.st_ino != file->inode 707 : ) { 708 6 : log_tag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub)); 709 6 : if (handle[j].st.st_size != file->size) { @@ -785,8 +785,8 @@ 723 6 : continue; 724 : } 725 : - 726 404920 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, log_error, 0); - 727 404920 : if (read_size == -1) { + 726 405735 : read_size = handle_read(&handle[j], file_pos, buffer[j], state->block_size, log_error, 0); + 727 405735 : if (read_size == -1) { 728 : /* LCOV_EXCL_START */ 729 : if (errno == EIO) { 730 : log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), file_pos, strerror(errno)); @@ -814,26 +814,26 @@ 752 : } 753 : 754 : /* until now is disk */ - 755 404920 : state_usage_disk(state, disk); + 755 405735 : state_usage_disk(state, disk); 756 : - 757 404920 : countsize += read_size; + 757 405735 : countsize += read_size; 758 : 759 : /* now compute the hash */ - 760 404920 : if (rehash) { + 760 405735 : if (rehash) { 761 52244 : memhash(state->prevhash, state->prevhashseed, hash, buffer[j], read_size); 762 : 763 : /* compute the new hash, and store it */ 764 52244 : rehandle[j].block = block; 765 52244 : memhash(state->hash, state->hashseed, rehandle[j].hash, buffer[j], read_size); 766 : } else { - 767 352676 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size); + 767 353491 : memhash(state->hash, state->hashseed, hash, buffer[j], read_size); 768 : } 769 : - 770 404920 : if (block_has_updated_hash(block)) { + 770 405735 : if (block_has_updated_hash(block)) { 771 : /* compare the hash */ - 772 280722 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { + 772 281416 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { 773 : /* if the file has invalid parity, it's a REP changed during the sync */ - 774 884 : if (block_has_invalid_parity(block)) { + 774 883 : if (block_has_invalid_parity(block)) { 775 1 : log_tag("error:%u:%s:%s: Unexpected data change\n", i, disk->name, esc(file->sub)); 776 1 : log_error("Data change at file '%s' at position '%u'\n", handle[j].path, file_pos); 777 1 : log_error("WARNING! Unexpected data modification of a file without parity!\n"); @@ -854,38 +854,38 @@ 792 1 : error_on_this_block = 1; 793 1 : continue; 794 : } else { /* otherwise it's a BLK with silent error */ - 795 883 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE); - 796 883 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff); - 797 883 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", handle[j].path, file_pos, diff); + 795 882 : unsigned diff = memdiff(hash, block->hash, HASH_SIZE); + 796 882 : log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff); + 797 882 : log_error("Data error in file '%s' at position '%u', diff bits %u\n", handle[j].path, file_pos, diff); 798 : 799 : /* save the failed block for the fix */ - 800 883 : failed[failed_count].index = j; - 801 883 : failed[failed_count].size = read_size; - 802 883 : failed[failed_count].block = block; - 803 883 : ++failed_count; + 800 882 : failed[failed_count].index = j; + 801 882 : failed[failed_count].size = read_size; + 802 882 : failed[failed_count].block = block; + 803 882 : ++failed_count; 804 : 805 : /* silent errors are very rare, and are not a signal that a disk */ 806 : /* is going to fail. So, we just continue marking the block as bad */ 807 : /* just like in scrub */ - 808 883 : ++silent_error; - 809 883 : silent_error_on_this_block = 1; - 810 883 : continue; + 808 882 : ++silent_error; + 809 882 : silent_error_on_this_block = 1; + 810 882 : continue; 811 : } 812 : } 813 : } else { 814 : /* if until now the parity doesn't need to be updated */ - 815 124198 : if (!parity_needs_to_be_updated) { + 815 124319 : if (!parity_needs_to_be_updated) { 816 : /* for sure it's a CHG block, because EMPTY are processed before with "continue" */ 817 : /* and BLK and REP have "block_has_updated_hash()" as 1, and all the others */ 818 : /* have "parity_needs_to_be_updated" already at 1 */ - 819 56621 : assert(block_state_get(block) == BLOCK_STATE_CHG); + 819 56741 : assert(block_state_get(block) == BLOCK_STATE_CHG); 820 : 821 : /* if there is an hash */ - 822 56621 : if (hash_is_real(block->hash)) { + 822 56741 : if (hash_is_real(block->hash)) { 823 : /* check if the hash is changed */ - 824 12894 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { + 824 13014 : if (memcmp(hash, block->hash, HASH_SIZE) != 0) { 825 : /* the block is different, and we must update parity */ - 826 10323 : parity_needs_to_be_updated = 1; + 826 10443 : parity_needs_to_be_updated = 1; 827 : } 828 : } else { 829 : /* if the hash is already invalid, we update parity */ @@ -895,7 +895,7 @@ 833 : 834 : /* copy the hash in the block, but doesn't mark the block as hashed */ 835 : /* this allow in case of skipped block to do not save the failed computation */ - 836 124198 : memcpy(block->hash, hash, HASH_SIZE); + 836 124319 : memcpy(block->hash, hash, HASH_SIZE); 837 : 838 : /* note that in case of rehash, this is the wrong hash, */ 839 : /* but it will be overwritten later */ @@ -905,52 +905,52 @@ 843 : /* if we have only silent errors we can try to fix them on-the-fly */ 844 : /* note the the fix is not written to disk, but used only to */ 845 : /* compute the new parity */ - 846 82210 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) { + 846 82341 : if (!error_on_this_block && !io_error_on_this_block && silent_error_on_this_block) { 847 : unsigned failed_mac; - 848 883 : int something_to_recover = 0; + 848 882 : int something_to_recover = 0; 849 : 850 : /* setup the blocks to recover */ - 851 883 : failed_mac = 0; - 852 2649 : for (j = 0; j < failed_count; ++j) { - 853 1766 : unsigned char* block_buffer = buffer[failed[j].index]; - 854 1766 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index]; - 855 1766 : unsigned block_state = block_state_get(failed[j].block); + 851 882 : failed_mac = 0; + 852 2646 : for (j = 0; j < failed_count; ++j) { + 853 1764 : unsigned char* block_buffer = buffer[failed[j].index]; + 854 1764 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index]; + 855 1764 : unsigned block_state = block_state_get(failed[j].block); 856 : 857 : /* we try to recover only if at least one BLK is present */ - 858 1766 : if (block_state == BLOCK_STATE_BLK) - 859 883 : something_to_recover = 1; + 858 1764 : if (block_state == BLOCK_STATE_BLK) + 859 882 : something_to_recover = 1; 860 : 861 : /* save a copy of the content just read */ 862 : /* that it's going to be overwritten by the recovering function */ - 863 1766 : memcpy(block_copy, block_buffer, state->block_size); + 863 1764 : memcpy(block_copy, block_buffer, state->block_size); 864 : - 865 1766 : if (block_state == BLOCK_STATE_CHG - 866 883 : && hash_is_zero(failed[j].block->hash) + 865 1764 : if (block_state == BLOCK_STATE_CHG + 866 882 : && hash_is_zero(failed[j].block->hash) 867 : ) { 868 : /* if the block was filled with 0, restore this state */ 869 : /* and avoid to recover it */ 870 0 : memset(block_buffer, 0, state->block_size); 871 : } else { 872 : /* if we have too many failures, we cannot recover */ - 873 1766 : if (failed_mac >= state->level) + 873 1764 : if (failed_mac >= state->level) 874 0 : break; 875 : 876 : /* otherwise it has to be recovered */ - 877 1766 : failed_map[failed_mac++] = failed[j].index; + 877 1764 : failed_map[failed_mac++] = failed[j].index; 878 : } 879 : } 880 : 881 : /* if we have something to recover and enough parity */ - 882 883 : if (something_to_recover && j == failed_count) { + 882 882 : if (something_to_recover && j == failed_count) { 883 : /* until now is CPU */ - 884 883 : state_usage_cpu(state); + 884 882 : state_usage_cpu(state); 885 : 886 : /* read the parity */ 887 : /* we are sure that parity exists because */ 888 : /* we have at least one BLK block */ - 889 6181 : for (l = 0; l < state->level; ++l) { - 890 5298 : ret = parity_read(parity[l], i, buffer[diskmax + l], state->block_size, log_error); - 891 5298 : if (ret == -1) { + 889 6174 : for (l = 0; l < state->level; ++l) { + 890 5292 : ret = parity_read(parity[l], i, buffer[diskmax + l], state->block_size, log_error); + 891 5292 : if (ret == -1) { 892 : /* LCOV_EXCL_START */ 893 : if (errno == EIO) { 894 : log_tag("parity_error:%u:%s: Read EIO error. %s\n", i, lev_config_name(l), strerror(errno)); @@ -978,74 +978,74 @@ 916 : } 917 : 918 : /* until now is parity */ - 919 5298 : state_usage_parity(state, l); + 919 5292 : state_usage_parity(state, l); 920 : } 921 : 922 : /* if no error in parity read */ - 923 883 : if (!io_error_on_this_block) { + 923 882 : if (!io_error_on_this_block) { 924 : /* try to fix the data */ 925 : /* note that this is a simple fix algorithm, that doesn't take into */ 926 : /* account the case of a wrong parity */ 927 : /* only 'fix' supports the most advanced fixing */ - 928 883 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer); + 928 882 : raid_rec(failed_mac, failed_map, diskmax, state->level, state->block_size, buffer); 929 : 930 : /* check the result and prepare the data */ - 931 5298 : for (j = 0; j < failed_count; ++j) { + 931 5292 : for (j = 0; j < failed_count; ++j) { 932 : unsigned char hash[HASH_SIZE]; - 933 1766 : unsigned char* block_buffer = buffer[failed[j].index]; - 934 1766 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index]; - 935 1766 : unsigned block_state = block_state_get(failed[j].block); + 933 1764 : unsigned char* block_buffer = buffer[failed[j].index]; + 934 1764 : unsigned char* block_copy = buffer[diskmax + state->level + failed[j].index]; + 935 1764 : unsigned block_state = block_state_get(failed[j].block); 936 : - 937 1766 : if (block_state == BLOCK_STATE_BLK) { - 938 883 : unsigned size = failed[j].size; + 937 1764 : if (block_state == BLOCK_STATE_BLK) { + 938 882 : unsigned size = failed[j].size; 939 : 940 : /* compute the hash of the recovered block */ - 941 883 : if (rehash) { + 941 882 : if (rehash) { 942 0 : memhash(state->prevhash, state->prevhashseed, hash, block_buffer, size); 943 : } else { - 944 883 : memhash(state->hash, state->hashseed, hash, block_buffer, size); + 944 882 : memhash(state->hash, state->hashseed, hash, block_buffer, size); 945 : } 946 : 947 : /* if the hash doesn't match */ - 948 883 : if (memcmp(hash, failed[j].block->hash, HASH_SIZE) != 0) { + 948 882 : if (memcmp(hash, failed[j].block->hash, HASH_SIZE) != 0) { 949 : /* we have not recovered */ 950 0 : break; 951 : } 952 : 953 : /* pad with 0 if needed */ - 954 883 : if (size < state->block_size) - 955 370 : memset(block_buffer + size, 0, state->block_size - size); + 954 882 : if (size < state->block_size) + 955 342 : memset(block_buffer + size, 0, state->block_size - size); 956 : } else { 957 : /* otherwise restore the content */ 958 : /* because we are not interested in the old state */ 959 : /* that it's recovered for CHG, REP and DELETED blocks */ - 960 883 : memcpy(block_buffer, block_copy, state->block_size); + 960 882 : memcpy(block_buffer, block_copy, state->block_size); 961 : } 962 : } 963 : 964 : /* if all is processed, we have fixed it */ - 965 883 : if (j == failed_count) - 966 883 : fixed_error_on_this_block = 1; + 965 882 : if (j == failed_count) + 966 882 : fixed_error_on_this_block = 1; 967 : } 968 : } 969 : } 970 : 971 : /* if we have read all the data required and it's correct, proceed with the parity */ - 972 82210 : if (!error_on_this_block && !io_error_on_this_block - 973 82191 : && (!silent_error_on_this_block || fixed_error_on_this_block) + 972 82341 : if (!error_on_this_block && !io_error_on_this_block + 973 82322 : && (!silent_error_on_this_block || fixed_error_on_this_block) 974 : ) { 975 : /* update the parity only if really needed */ - 976 82191 : if (parity_needs_to_be_updated) { + 976 82322 : if (parity_needs_to_be_updated) { 977 : /* compute the parity */ - 978 79852 : raid_gen(diskmax, state->level, state->block_size, buffer); + 978 79972 : raid_gen(diskmax, state->level, state->block_size, buffer); 979 : 980 : /* until now is CPU */ - 981 79852 : state_usage_cpu(state); + 981 79972 : state_usage_cpu(state); 982 : 983 : /* write the parity */ - 984 522644 : for (l = 0; l < state->level; ++l) { - 985 442792 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size); - 986 442792 : if (ret == -1) { + 984 523484 : for (l = 0; l < state->level; ++l) { + 985 443512 : ret = parity_write(parity[l], i, buffer[diskmax + l], state->block_size); + 986 443512 : if (ret == -1) { 987 : /* LCOV_EXCL_START */ 988 : if (errno == EIO) { 989 : log_tag("parity_error:%u:%s: Write EIO error. %s\n", i, lev_config_name(l), strerror(errno)); @@ -1073,35 +1073,35 @@ 1011 : } 1012 : 1013 : /* until now is parity */ - 1014 442792 : state_usage_parity(state, l); + 1014 443512 : state_usage_parity(state, l); 1015 : } 1016 : } 1017 : 1018 : /* if no error in parity write */ - 1019 82191 : if (!io_error_on_this_block) { + 1019 82322 : if (!io_error_on_this_block) { 1020 : /* for each disk, mark the blocks as processed */ - 1021 575337 : for (j = 0; j < diskmax; ++j) { + 1021 576254 : for (j = 0; j < diskmax; ++j) { 1022 : struct snapraid_block* block; 1023 : - 1024 493146 : if (!handle[j].disk) + 1024 493932 : if (!handle[j].disk) 1025 0 : continue; 1026 : - 1027 493146 : block = fs_par2block_get(handle[j].disk, i); + 1027 493932 : block = fs_par2block_get(handle[j].disk, i); 1028 : - 1029 493146 : if (block == BLOCK_EMPTY) { + 1029 493932 : if (block == BLOCK_EMPTY) { 1030 : /* nothing to do */ - 1031 77254 : continue; + 1031 77225 : continue; 1032 : } 1033 : 1034 : /* if it's a deleted block */ - 1035 415892 : if (block_state_get(block) == BLOCK_STATE_DELETED) { + 1035 416707 : if (block_state_get(block) == BLOCK_STATE_DELETED) { 1036 : /* the parity is now updated without this block, so it's now empty */ 1037 11066 : fs_deallocate(handle[j].disk, i); 1038 11066 : continue; 1039 : } 1040 : 1041 : /* now all the blocks have the hash and the parity computed */ - 1042 404826 : block_state_set(block, BLOCK_STATE_BLK); + 1042 405641 : block_state_set(block, BLOCK_STATE_BLK); 1043 : } 1044 : } 1045 : @@ -1110,12 +1110,12 @@ 1048 : /* wrote the parity at this time */ 1049 : /* we also update the info block only if no silent error was found */ 1050 : /* because has no sense to refresh the time for data that we know bad */ - 1051 82191 : if (parity_needs_to_be_updated - 1052 79852 : && !silent_error_on_this_block - 1053 79501 : && !io_error_on_this_block + 1051 82322 : if (parity_needs_to_be_updated + 1052 79972 : && !silent_error_on_this_block + 1053 79625 : && !io_error_on_this_block 1054 : ) { 1055 : /* if rehash is neeed */ - 1056 79501 : if (rehash) { + 1056 79625 : if (rehash) { 1057 : /* store all the new hash already computed */ 1058 64358 : for (j = 0; j < diskmax; ++j) { 1059 55164 : if (rehandle[j].block) @@ -1125,37 +1125,37 @@ 1063 : 1064 : /* update the time info of the block */ 1065 : /* we are also clearing any previous bad and rehash flag */ - 1066 79501 : info_set(&state->infoarr, i, info_make(now, 0, 0, 1)); + 1066 79625 : info_set(&state->infoarr, i, info_make(now, 0, 0, 1)); 1067 : } 1068 : } 1069 : 1070 : /* if a silent (even if corrected) or input/output error was found */ 1071 : /* mark the block as bad to have check/fix to handle it */ 1072 : /* because our correction is in memory only and not yet written */ - 1073 82210 : if (silent_error_on_this_block || io_error_on_this_block) { + 1073 82341 : if (silent_error_on_this_block || io_error_on_this_block) { 1074 : /* set the error status keeping the other info */ - 1075 883 : info_set(&state->infoarr, i, info_set_bad(info)); + 1075 882 : info_set(&state->infoarr, i, info_set_bad(info)); 1076 : } 1077 : 1078 : /* mark the state as needing write */ - 1079 82210 : state->need_write = 1; + 1079 82341 : state->need_write = 1; 1080 : 1081 : /* count the number of processed block */ - 1082 82210 : ++countpos; + 1082 82341 : ++countpos; 1083 : 1084 : /* progress */ - 1085 82210 : if (state_progress(state, i, countpos, countmax, countsize)) { + 1085 82341 : if (state_progress(state, i, countpos, countmax, countsize)) { 1086 : /* LCOV_EXCL_START */ 1087 : break; 1088 : /* LCOV_EXCL_STOP */ 1089 : } 1090 : 1091 : /* autosave */ - 1092 82210 : if ((state->autosave != 0 + 1092 82341 : if ((state->autosave != 0 1093 7264 : && autosavedone >= autosavelimit /* if we have reached the limit */ 1094 0 : && autosavemissing >= autosavelimit) /* if we have at least a full step to do */ 1095 : /* or if we have a forced autosave at the specified block */ - 1096 82210 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == i) + 1096 82341 : || (state->opt.force_autosave_at != 0 && state->opt.force_autosave_at == i) 1097 : ) { 1098 1 : autosavedone = 0; /* restart the counter */ 1099 : diff --git a/cov/cmdline/unix.c.func-sort-c.html b/cov/cmdline/unix.c.func-sort-c.html index 530cc0fa..5b352a9b 100644 --- a/cov/cmdline/unix.c.func-sort-c.html +++ b/cov/cmdline/unix.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 21 @@ -61,15 +61,15 @@ tick - 2046547 + 2049010 open_noatime - 1639793 + 1640600 filephy - 11430 + 11432 devuuid diff --git a/cov/cmdline/unix.c.func.html b/cov/cmdline/unix.c.func.html index 494539a3..bd939ad7 100644 --- a/cov/cmdline/unix.c.func.html +++ b/cov/cmdline/unix.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 21 @@ -105,7 +105,7 @@ filephy - 11430 + 11432 fsinfo @@ -113,7 +113,7 @@ open_noatime - 1639793 + 1640600 os_done @@ -145,7 +145,7 @@ tick - 2046547 + 2049010 tick_ms diff --git a/cov/cmdline/unix.c.gcov.html b/cov/cmdline/unix.c.gcov.html index 18f63c6b..3a428fcf 100644 --- a/cov/cmdline/unix.c.gcov.html +++ b/cov/cmdline/unix.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 21 @@ -90,15 +90,15 @@ 28 : int exit_failure = 1; 29 : int exit_sync_needed = 2; 30 : - 31 1639793 : int open_noatime(const char* file, int flags) + 31 1640600 : int open_noatime(const char* file, int flags) 32 : { 33 : #ifdef O_NOATIME - 34 1639793 : int f = open(file, flags | O_NOATIME); + 34 1640600 : int f = open(file, flags | O_NOATIME); 35 : 36 : /* only root is allowed to use O_NOATIME, in case retry without it */ - 37 1639793 : if (f == -1 && errno == EPERM) + 37 1640600 : if (f == -1 && errno == EPERM) 38 0 : f = open(file, flags); - 39 1639793 : return f; + 39 1640600 : return f; 40 : #else 41 : return open(file, flags); 42 : #endif @@ -185,7 +185,7 @@ 123 : } 124 : #endif 125 : - 126 11430 : int filephy(const char* path, uint64_t size, uint64_t* physical) + 126 11432 : int filephy(const char* path, uint64_t size, uint64_t* physical) 127 : { 128 : #if HAVE_LINUX_FIEMAP_H 129 : /* In Linux get the real physical address of the file */ @@ -197,24 +197,24 @@ 135 : } fm; 136 : unsigned int blknum; 137 : - 138 11430 : f = open(path, O_RDONLY); - 139 11430 : if (f == -1) { + 138 11432 : f = open(path, O_RDONLY); + 139 11432 : if (f == -1) { 140 0 : return -1; 141 : } 142 : 143 : /* first try with FIEMAP */ 144 : /* if works for ext2, ext3, ext4, xfs, btrfs */ - 145 11430 : memset(&fm, 0, sizeof(fm)); - 146 11430 : fm.fiemap.fm_start = 0; - 147 11430 : fm.fiemap.fm_length = ~0ULL; - 148 11430 : fm.fiemap.fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */ - 149 11430 : fm.fiemap.fm_extent_count = 1; /* we are interested only at the first block */ + 145 11432 : memset(&fm, 0, sizeof(fm)); + 146 11432 : fm.fiemap.fm_start = 0; + 147 11432 : fm.fiemap.fm_length = ~0ULL; + 148 11432 : fm.fiemap.fm_flags = FIEMAP_FLAG_SYNC; /* required to ensure that just created files report a valid address and not 0 */ + 149 11432 : fm.fiemap.fm_extent_count = 1; /* we are interested only at the first block */ 150 : - 151 11430 : if (ioctl(f, FS_IOC_FIEMAP, &fm) != -1) { - 152 11430 : *physical = fm.fiemap.fm_extents[0].fe_physical + FILEPHY_REAL_OFFSET; - 153 11430 : if (close(f) == -1) + 151 11432 : if (ioctl(f, FS_IOC_FIEMAP, &fm) != -1) { + 152 11432 : *physical = fm.fiemap.fm_extents[0].fe_physical + FILEPHY_REAL_OFFSET; + 153 11432 : if (close(f) == -1) 154 0 : return -1; - 155 11430 : return 0; + 155 11432 : return 0; 156 : } 157 : 158 : /* if the file is empty, FIBMAP doesn't work, and we don't even try to use it */ @@ -324,7 +324,7 @@ 262 2175 : return 0; 263 : } 264 : - 265 2046547 : uint64_t tick(void) + 265 2049010 : uint64_t tick(void) 266 : { 267 : #if HAVE_MACH_ABSOLUTE_TIME 268 : /* for Mac OS X */ @@ -335,14 +335,14 @@ 273 : 274 : /* nanosecond precision with clock_gettime() */ 275 : #if defined(CLOCK_MONOTONIC_RAW) - 276 2046547 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) { + 276 2049010 : if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) { 277 : #else 278 : if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) { 279 : #endif 280 0 : return 0; 281 : } 282 : - 283 2046547 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec; + 283 2049010 : return tv.tv_sec * 1000000000ULL + tv.tv_nsec; 284 : #else 285 : /* other platforms */ 286 : struct timeval tv; @@ -504,14 +504,14 @@ 442 : return -1; 443 : /* LCOV_EXCL_STOP */ 444 : } - 445 96 : if (st.st_rdev != device) { + 445 97 : if (st.st_rdev != device) { 446 : /* LCOV_EXCL_START */ 447 : log_fatal("Unexpected device '%u:%u' instead of '%u:%u' for '%s'.\n", major(st.st_rdev), minor(st.st_rdev), major(device), minor(device), path); 448 : return -1; 449 : /* LCOV_EXCL_STOP */ 450 : } 451 : - 452 96 : return 0; + 452 97 : return 0; 453 : } 454 : #endif 455 : diff --git a/cov/cmdline/util.c.func-sort-c.html b/cov/cmdline/util.c.func-sort-c.html index f58dadb1..8fc8b9ea 100644 --- a/cov/cmdline/util.c.func-sort-c.html +++ b/cov/cmdline/util.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 14 @@ -61,35 +61,35 @@ util_rotl32 - 924868918 + 924861211 util_rotl64 - 461100864 + 461015664 memhash - 5723453 + 5724756 crc32c_x86 - 659437 + 659527 memdiff - 25256 + 25190 malloc_nofail_test - 2579 + 2580 mtest_vector - 2579 + 2580 crc32c_gen - 337 + 353 crc32c_init diff --git a/cov/cmdline/util.c.func.html b/cov/cmdline/util.c.func.html index 878fbb41..a05830bd 100644 --- a/cov/cmdline/util.c.func.html +++ b/cov/cmdline/util.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 14 @@ -61,7 +61,7 @@ crc32c_gen - 337 + 353 crc32c_init @@ -69,7 +69,7 @@ crc32c_x86 - 659437 + 659527 hash_config_name @@ -89,7 +89,7 @@ malloc_nofail_test - 2579 + 2580 malloc_nofail_vector_align @@ -97,23 +97,23 @@ memdiff - 25256 + 25190 memhash - 5723453 + 5724756 mtest_vector - 2579 + 2580 util_rotl32 - 924868918 + 924861211 util_rotl64 - 461100864 + 461015664
diff --git a/cov/cmdline/util.c.gcov.html b/cov/cmdline/util.c.gcov.html index 466752f2..501f3b20 100644 --- a/cov/cmdline/util.c.gcov.html +++ b/cov/cmdline/util.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 14 @@ -119,20 +119,20 @@ 57 201 : return ptr; 58 : } 59 : - 60 2579 : void* malloc_nofail_test(size_t size) + 60 2580 : void* malloc_nofail_test(size_t size) 61 : { 62 : void* ptr; 63 : - 64 2579 : ptr = malloc_nofail(size); + 64 2580 : ptr = malloc_nofail(size); 65 : - 66 2578 : mtest_vector(1, size, &ptr); + 66 2580 : mtest_vector(1, size, &ptr); 67 : 68 2580 : return ptr; 69 : } 70 : - 71 2579 : void mtest_vector(int n, size_t size, void** vv) + 71 2580 : void mtest_vector(int n, size_t size, void** vv) 72 : { - 73 2579 : if (raid_mtest_vector(n, size, vv) != 0) { + 73 2580 : if (raid_mtest_vector(n, size, vv) != 0) { 74 : /* LCOV_EXCL_START */ 75 : log_fatal("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n"); 76 : log_fatal("Try running a memory test like http://www.memtest86.com/\n"); @@ -416,27 +416,27 @@ 354 : int crc_x86; 355 : #endif 356 : - 357 337 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size) + 357 353 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size) 358 : { - 359 337 : crc ^= CRC_IV; + 359 353 : crc ^= CRC_IV; 360 : - 361 337 : crc = crc32c_gen_plain(crc, ptr, size); + 361 353 : crc = crc32c_gen_plain(crc, ptr, size); 362 : - 363 337 : crc ^= CRC_IV; + 363 353 : crc ^= CRC_IV; 364 : - 365 337 : return crc; + 365 353 : return crc; 366 : } 367 : 368 : #if HAVE_SSE42 - 369 659437 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size) + 369 659527 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size) 370 : { - 371 659437 : crc ^= CRC_IV; + 371 659527 : crc ^= CRC_IV; 372 : - 373 659437 : crc = crc32c_x86_plain(crc, ptr, size); + 373 659527 : crc = crc32c_x86_plain(crc, ptr, size); 374 : - 375 659437 : crc ^= CRC_IV; + 375 659526 : crc ^= CRC_IV; 376 : - 377 659437 : return crc; + 377 659526 : return crc; 378 : } 379 : #endif 380 : @@ -460,14 +460,14 @@ 398 : * Rotate left. 399 : * In x86/x64 they are optimized with a single assembler instruction. 400 : */ - 401 924868918 : static inline uint32_t util_rotl32(uint32_t x, int8_t r) + 401 924861211 : static inline uint32_t util_rotl32(uint32_t x, int8_t r) 402 : { - 403 924868918 : return (x << r) | (x >> (32 - r)); + 403 924861211 : return (x << r) | (x >> (32 - r)); 404 : } 405 : - 406 461100864 : static inline uint64_t util_rotl64(uint64_t x, int8_t r) + 406 461015664 : static inline uint64_t util_rotl64(uint64_t x, int8_t r) 407 : { - 408 461100864 : return (x << r) | (x >> (64 - r)); + 408 461015664 : return (x << r) | (x >> (64 - r)); 409 : } 410 : 411 : /** @@ -508,15 +508,15 @@ 446 : #include "murmur3.c" 447 : #include "spooky2.c" 448 : - 449 5723453 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size) + 449 5724756 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size) 450 : { - 451 5723453 : switch (kind) { + 451 5724756 : switch (kind) { 452 : case HASH_MURMUR3 : - 453 2252580 : MurmurHash3_x86_128(src, size, seed, digest); - 454 2252580 : break; + 453 2252582 : MurmurHash3_x86_128(src, size, seed, digest); + 454 2252582 : break; 455 : case HASH_SPOOKY2 : - 456 3470873 : SpookyHash128(src, size, seed, digest); - 457 3470873 : break; + 456 3472174 : SpookyHash128(src, size, seed, digest); + 457 3472174 : break; 458 : default : 459 : /* LCOV_EXCL_START */ 460 : log_fatal("Internal inconsistency in hash function %u\n", kind); @@ -524,7 +524,7 @@ 462 : break; 463 : /* LCOV_EXCL_STOP */ 464 : } - 465 5723453 : } + 465 5724756 : } 466 : 467 42 : const char* hash_config_name(unsigned kind) 468 : { @@ -539,23 +539,23 @@ 477 : } 478 : } 479 : - 480 25256 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size) + 480 25190 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size) 481 : { 482 : size_t i; 483 : unsigned count; 484 : - 485 25256 : count = 0; - 486 11152456 : for (i = 0; i < size; ++i) { + 485 25190 : count = 0; + 486 11153350 : for (i = 0; i < size; ++i) { 487 : unsigned j; - 488 11127200 : unsigned char diff = data1[i] ^ data2[i]; - 489 100144800 : for (j = 0; j < 8; ++j) { - 490 89017600 : if ((diff & 1) != 0) - 491 39280018 : ++count; - 492 89017600 : diff >>= 1; + 488 11128160 : unsigned char diff = data1[i] ^ data2[i]; + 489 100153440 : for (j = 0; j < 8; ++j) { + 490 89025280 : if ((diff & 1) != 0) + 491 39291929 : ++count; + 492 89025280 : diff >>= 1; 493 : } 494 : } 495 : - 496 25256 : return 0; + 496 25190 : return 0; 497 : } 498 : 499 : /****************************************************************************/ diff --git a/cov/cmdline/util.h.func-sort-c.html b/cov/cmdline/util.h.func-sort-c.html index f8ed6e45..aba2a712 100644 --- a/cov/cmdline/util.h.func-sort-c.html +++ b/cov/cmdline/util.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -61,19 +61,19 @@ crc32c_x86_plain - 131430214 + 131602718 crc32c_plain - 130044002 + 128046334 crc32c_plain_char - 23710549 + 23675077 crc32c_gen_plain - 337 + 353
diff --git a/cov/cmdline/util.h.func.html b/cov/cmdline/util.h.func.html index cd6b9d13..92bc1cda 100644 --- a/cov/cmdline/util.h.func.html +++ b/cov/cmdline/util.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -61,19 +61,19 @@ crc32c_gen_plain - 337 + 353 crc32c_plain - 130044002 + 128046334 crc32c_plain_char - 23710549 + 23675077 crc32c_x86_plain - 131430214 + 131602718
diff --git a/cov/cmdline/util.h.gcov.html b/cov/cmdline/util.h.gcov.html index a65119b9..a736fd08 100644 --- a/cov/cmdline/util.h.gcov.html +++ b/cov/cmdline/util.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -133,12 +133,12 @@ 71 : /** 72 : * Compute CRC-32 (Castagnoli) for a single byte without the IV. 73 : */ - 74 23710549 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c) + 74 23675077 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c) 75 : { 76 : #if HAVE_SSE42 - 77 23710549 : if (tommy_likely(crc_x86)) { - 78 23710549 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c)); - 79 23710549 : return crc; + 77 23675077 : if (tommy_likely(crc_x86)) { + 78 23675077 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (c)); + 79 23675077 : return crc; 80 : } 81 : #endif 82 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8); @@ -147,29 +147,29 @@ 85 : /** 86 : * Compute the CRC-32 (Castagnoli) without the IV. 87 : */ - 88 337 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size) + 88 353 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size) 89 : { - 90 20972361 : while (size >= 4) { - 91 20971687 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24; - 92 20971687 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24]; - 93 20971687 : ptr += 4; - 94 20971687 : size -= 4; + 90 22020969 : while (size >= 4) { + 91 22020263 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24; + 92 22020263 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24]; + 93 22020263 : ptr += 4; + 94 22020263 : size -= 4; 95 : } 96 : - 97 683 : while (size) { + 97 715 : while (size) { 98 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8); 99 9 : ++ptr; 100 9 : --size; 101 : } 102 : - 103 337 : return crc; + 103 353 : return crc; 104 : } 105 : 106 : /** 107 : * Compute the CRC-32 (Castagnoli) without the IV. 108 : */ 109 : #if HAVE_SSE42 - 110 131430214 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size) + 110 131602718 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size) 111 : { 112 : #ifdef CONFIG_X86_64 113 : uint64_t crc64 = crc; @@ -180,30 +180,30 @@ 118 : } 119 : crc = crc64; 120 : #else - 121 972142050 : while (size >= 4) { - 122 709281622 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr)); - 123 709281622 : ptr += 4; - 124 709281622 : size -= 4; + 121 969717854 : while (size >= 4) { + 122 706512418 : asm("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr)); + 123 706512418 : ptr += 4; + 124 706512418 : size -= 4; 125 : } 126 : #endif - 127 382290808 : while (size) { - 128 119430380 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr)); - 129 119430380 : ++ptr; - 130 119430380 : --size; + 127 382941674 : while (size) { + 128 119736238 : asm("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr)); + 129 119736238 : ++ptr; + 130 119736238 : --size; 131 : } 132 : - 133 131430214 : return crc; + 133 131602718 : return crc; 134 : } 135 : #endif 136 : 137 : /** 138 : * Compute CRC-32 (Castagnoli) without the IV. 139 : */ - 140 130044002 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size) + 140 128046334 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size) 141 : { 142 : #if HAVE_SSE42 - 143 130044002 : if (tommy_likely(crc_x86)) { - 144 130044002 : return crc32c_x86_plain(crc, ptr, size); + 143 128046334 : if (tommy_likely(crc_x86)) { + 144 128046334 : return crc32c_x86_plain(crc, ptr, size); 145 : } 146 : #endif 147 0 : return crc32c_gen_plain(crc, ptr, size); diff --git a/cov/index-sort-f.html b/cov/index-sort-f.html index b5b5ab5f..bc18c20f 100644 --- a/cov/index-sort-f.html +++ b/cov/index-sort-f.html @@ -31,13 +31,13 @@ lcov.info Lines: - 9664 - 10366 + 9667 + 10368 93.2 % Date: - 2015-11-13 + 2015-11-20 Functions: 553 @@ -75,7 +75,7 @@
91.4%91.4%
91.4 % - 7341 / 8031 + 7344 / 8033 97.7 % 388 / 397 diff --git a/cov/index-sort-l.html b/cov/index-sort-l.html index 82ba3791..5f59d954 100644 --- a/cov/index-sort-l.html +++ b/cov/index-sort-l.html @@ -31,13 +31,13 @@ lcov.info Lines: - 9664 - 10366 + 9667 + 10368 93.2 % Date: - 2015-11-13 + 2015-11-20 Functions: 553 @@ -75,7 +75,7 @@
91.4%91.4%
91.4 % - 7341 / 8031 + 7344 / 8033 97.7 % 388 / 397 diff --git a/cov/index.html b/cov/index.html index 53c8f1f6..abaf833c 100644 --- a/cov/index.html +++ b/cov/index.html @@ -31,13 +31,13 @@ lcov.info Lines: - 9664 - 10366 + 9667 + 10368 93.2 % Date: - 2015-11-13 + 2015-11-20 Functions: 553 @@ -75,7 +75,7 @@
91.4%91.4%
91.4 % - 7341 / 8031 + 7344 / 8033 97.7 % 388 / 397 diff --git a/cov/raid/check.c.func-sort-c.html b/cov/raid/check.c.func-sort-c.html index bb79ab19..0c9b19f8 100644 --- a/cov/raid/check.c.func-sort-c.html +++ b/cov/raid/check.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/raid/check.c.func.html b/cov/raid/check.c.func.html index dc423ebe..eaef437a 100644 --- a/cov/raid/check.c.func.html +++ b/cov/raid/check.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/raid/check.c.gcov.html b/cov/raid/check.c.gcov.html index 94c6c33d..7b809175 100644 --- a/cov/raid/check.c.gcov.html +++ b/cov/raid/check.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/raid/combo.h.func-sort-c.html b/cov/raid/combo.h.func-sort-c.html index a906c074..9dc0148a 100644 --- a/cov/raid/combo.h.func-sort-c.html +++ b/cov/raid/combo.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 diff --git a/cov/raid/combo.h.func.html b/cov/raid/combo.h.func.html index c1c1d847..428b1c38 100644 --- a/cov/raid/combo.h.func.html +++ b/cov/raid/combo.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 diff --git a/cov/raid/combo.h.gcov.html b/cov/raid/combo.h.gcov.html index 8212c725..b8f76138 100644 --- a/cov/raid/combo.h.gcov.html +++ b/cov/raid/combo.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 @@ -170,10 +170,10 @@ 108 : int i; 109 : 110 : (void)n; /* unused, but kept for clarity */ - 111 215892 : assert(0 < r && r <= n); + 111 215930 : assert(0 < r && r <= n); 112 : - 113 713955 : for (i = 0; i < r; ++i) - 114 498063 : c[i] = i; + 113 713829 : for (i = 0; i < r; ++i) + 114 497899 : c[i] = i; 115 : } 116 : 117 : /** @@ -182,19 +182,19 @@ 120 : */ 121 : static __always_inline int combination_next(int r, int n, int *c) 122 : { - 123 51682 : int i = r - 1; /* present position */ - 124 51682 : int h = n; /* high limit for this position */ + 123 51676 : int i = r - 1; /* present position */ + 124 51676 : int h = n; /* high limit for this position */ 125 : 126 : recurse: 127 : /* next element at position i */ - 128 84555 : ++c[i]; + 128 84549 : ++c[i]; 129 : 130 : /* if the position has reached the max */ - 131 84555 : if (c[i] >= h) { + 131 84549 : if (c[i] >= h) { 132 : 133 : /* if we are at the first level, we have finished */ - 134 44861 : if (i == 0) - 135 11988 : return 0; + 134 44859 : if (i == 0) + 135 11986 : return 0; 136 : 137 : /* increase the previous position */ 138 32873 : --i; @@ -202,16 +202,16 @@ 140 : goto recurse; 141 : } 142 : - 143 39694 : ++i; + 143 39690 : ++i; 144 : 145 : /* initialize all the next positions, if any */ - 146 62239 : while (i < r) { + 146 62235 : while (i < r) { 147 : /* each position start at the next value of the previous one */ 148 22545 : c[i] = c[i - 1] + 1; 149 22545 : ++i; 150 : } 151 : - 152 39694 : return 1; + 152 39690 : return 1; 153 : } 154 : #endif 155 : diff --git a/cov/raid/cpu.h.func-sort-c.html b/cov/raid/cpu.h.func-sort-c.html index 54a94735..8c4e735a 100644 --- a/cov/raid/cpu.h.func-sort-c.html +++ b/cov/raid/cpu.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 12 diff --git a/cov/raid/cpu.h.func.html b/cov/raid/cpu.h.func.html index fa1818ef..d313f5e0 100644 --- a/cov/raid/cpu.h.func.html +++ b/cov/raid/cpu.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 12 diff --git a/cov/raid/cpu.h.gcov.html b/cov/raid/cpu.h.gcov.html index 6fadda4b..af6259db 100644 --- a/cov/raid/cpu.h.gcov.html +++ b/cov/raid/cpu.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 12 diff --git a/cov/raid/gf.h.func-sort-c.html b/cov/raid/gf.h.func-sort-c.html index b9170894..38e50d01 100644 --- a/cov/raid/gf.h.func-sort-c.html +++ b/cov/raid/gf.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 diff --git a/cov/raid/gf.h.func.html b/cov/raid/gf.h.func.html index a4a7aedc..d99cf543 100644 --- a/cov/raid/gf.h.func.html +++ b/cov/raid/gf.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 diff --git a/cov/raid/gf.h.gcov.html b/cov/raid/gf.h.gcov.html index c9464223..f7076a13 100644 --- a/cov/raid/gf.h.gcov.html +++ b/cov/raid/gf.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 @@ -88,7 +88,7 @@ 26 : */ 27 : static __always_inline uint8_t mul(uint8_t a, uint8_t b) 28 : { - 29 23816594 : return gfmul[a][b]; + 29 23813346 : return gfmul[a][b]; 30 : } 31 : 32 : /* @@ -97,9 +97,9 @@ 35 : */ 36 : static __always_inline uint8_t inv(uint8_t v) 37 : { - 38 635932 : BUG_ON(v == 0); /* division by zero */ + 38 635522 : BUG_ON(v == 0); /* division by zero */ 39 : - 40 635932 : return gfinv[v]; + 40 635522 : return gfinv[v]; 41 : } 42 : 43 : /* @@ -125,7 +125,7 @@ 63 : */ 64 : static __always_inline uint8_t A(int p, int d) 65 : { - 66 2606682 : return gfgen[p][d]; + 66 2605866 : return gfgen[p][d]; 67 : } 68 : 69 : /* diff --git a/cov/raid/helper.c.func-sort-c.html b/cov/raid/helper.c.func-sort-c.html index 84cfdf7e..47ed9277 100644 --- a/cov/raid/helper.c.func-sort-c.html +++ b/cov/raid/helper.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/raid/helper.c.func.html b/cov/raid/helper.c.func.html index b927219b..d1b46f34 100644 --- a/cov/raid/helper.c.func.html +++ b/cov/raid/helper.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/raid/helper.c.gcov.html b/cov/raid/helper.c.gcov.html index 229f4149..16b6e3f4 100644 --- a/cov/raid/helper.c.gcov.html +++ b/cov/raid/helper.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/raid/index-sort-f.html b/cov/raid/index-sort-f.html index 72129cda..53f2d677 100644 --- a/cov/raid/index-sort-f.html +++ b/cov/raid/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 83 diff --git a/cov/raid/index-sort-l.html b/cov/raid/index-sort-l.html index c412a33b..194b0b2c 100644 --- a/cov/raid/index-sort-l.html +++ b/cov/raid/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 83 diff --git a/cov/raid/index.html b/cov/raid/index.html index 5fecc0b8..c0b34a7b 100644 --- a/cov/raid/index.html +++ b/cov/raid/index.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 83 diff --git a/cov/raid/int.c.func-sort-c.html b/cov/raid/int.c.func-sort-c.html index dc8cdc86..1e9686f8 100644 --- a/cov/raid/int.c.func-sort-c.html +++ b/cov/raid/int.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 @@ -101,7 +101,7 @@ raid_gen6_int8 - 15 + 16
diff --git a/cov/raid/int.c.func.html b/cov/raid/int.c.func.html index e58f1a52..a9474d76 100644 --- a/cov/raid/int.c.func.html +++ b/cov/raid/int.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 @@ -89,7 +89,7 @@ raid_gen6_int8 - 15 + 16 raid_rec1_int8 diff --git a/cov/raid/int.c.gcov.html b/cov/raid/int.c.gcov.html index 784c1745..c6a492cd 100644 --- a/cov/raid/int.c.gcov.html +++ b/cov/raid/int.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 @@ -379,9 +379,9 @@ 317 : * But this is only a kind of reference function, and we are not really 318 : * interested in speed. 319 : */ - 320 15 : void raid_gen6_int8(int nd, size_t size, void **vv) + 320 16 : void raid_gen6_int8(int nd, size_t size, void **vv) 321 : { - 322 15 : uint8_t **v = (uint8_t **)vv; + 322 16 : uint8_t **v = (uint8_t **)vv; 323 : uint8_t *p; 324 : uint8_t *q; 325 : uint8_t *r; @@ -393,45 +393,45 @@ 331 : 332 : uint8_t d0, u0, t0, s0, r0, q0, p0; 333 : - 334 15 : l = nd - 1; - 335 15 : p = v[nd]; - 336 15 : q = v[nd + 1]; - 337 15 : r = v[nd + 2]; - 338 15 : s = v[nd + 3]; - 339 15 : t = v[nd + 4]; - 340 15 : u = v[nd + 5]; + 334 16 : l = nd - 1; + 335 16 : p = v[nd]; + 336 16 : q = v[nd + 1]; + 337 16 : r = v[nd + 2]; + 338 16 : s = v[nd + 3]; + 339 16 : t = v[nd + 4]; + 340 16 : u = v[nd + 5]; 341 : - 342 3408399 : for (i = 0; i < size; i += 1) { - 343 3408384 : p0 = q0 = r0 = s0 = t0 = u0 = 0; - 344 27271424 : for (d = l; d > 0; --d) { - 345 23863040 : d0 = v_8(v[d][i]); + 342 3670544 : for (i = 0; i < size; i += 1) { + 343 3670528 : p0 = q0 = r0 = s0 = t0 = u0 = 0; + 344 29368576 : for (d = l; d > 0; --d) { + 345 25698048 : d0 = v_8(v[d][i]); 346 : - 347 23863040 : p0 ^= d0; - 348 23863040 : q0 ^= gfmul[d0][gfgen[1][d]]; - 349 23863040 : r0 ^= gfmul[d0][gfgen[2][d]]; - 350 23863040 : s0 ^= gfmul[d0][gfgen[3][d]]; - 351 23863040 : t0 ^= gfmul[d0][gfgen[4][d]]; - 352 23863040 : u0 ^= gfmul[d0][gfgen[5][d]]; + 347 25698048 : p0 ^= d0; + 348 25698048 : q0 ^= gfmul[d0][gfgen[1][d]]; + 349 25698048 : r0 ^= gfmul[d0][gfgen[2][d]]; + 350 25698048 : s0 ^= gfmul[d0][gfgen[3][d]]; + 351 25698048 : t0 ^= gfmul[d0][gfgen[4][d]]; + 352 25698048 : u0 ^= gfmul[d0][gfgen[5][d]]; 353 : } 354 : 355 : /* first disk with all coefficients at 1 */ - 356 3408384 : d0 = v_8(v[0][i]); + 356 3670528 : d0 = v_8(v[0][i]); 357 : - 358 3408384 : p0 ^= d0; - 359 3408384 : q0 ^= d0; - 360 3408384 : r0 ^= d0; - 361 3408384 : s0 ^= d0; - 362 3408384 : t0 ^= d0; - 363 3408384 : u0 ^= d0; + 358 3670528 : p0 ^= d0; + 359 3670528 : q0 ^= d0; + 360 3670528 : r0 ^= d0; + 361 3670528 : s0 ^= d0; + 362 3670528 : t0 ^= d0; + 363 3670528 : u0 ^= d0; 364 : - 365 3408384 : v_8(p[i]) = p0; - 366 3408384 : v_8(q[i]) = q0; - 367 3408384 : v_8(r[i]) = r0; - 368 3408384 : v_8(s[i]) = s0; - 369 3408384 : v_8(t[i]) = t0; - 370 3408384 : v_8(u[i]) = u0; + 365 3670528 : v_8(p[i]) = p0; + 366 3670528 : v_8(q[i]) = q0; + 367 3670528 : v_8(r[i]) = r0; + 368 3670528 : v_8(s[i]) = s0; + 369 3670528 : v_8(t[i]) = t0; + 370 3670528 : v_8(u[i]) = u0; 371 : } - 372 15 : } + 372 16 : } 373 : 374 : /* 375 : * Recover failure of one data block at index id[0] using parity at index diff --git a/cov/raid/internal.h.func-sort-c.html b/cov/raid/internal.h.func-sort-c.html index 342c2783..3b75e83e 100644 --- a/cov/raid/internal.h.func-sort-c.html +++ b/cov/raid/internal.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 diff --git a/cov/raid/internal.h.func.html b/cov/raid/internal.h.func.html index 51989154..ee4ceee8 100644 --- a/cov/raid/internal.h.func.html +++ b/cov/raid/internal.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 diff --git a/cov/raid/internal.h.gcov.html b/cov/raid/internal.h.gcov.html index c3a2c986..3e410102 100644 --- a/cov/raid/internal.h.gcov.html +++ b/cov/raid/internal.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 0 @@ -159,11 +159,11 @@ 97 : */ 98 : static __always_inline void *__align_ptr(void *ptr, uintptr_t size) 99 : { - 100 696867 : uintptr_t offset = (uintptr_t)ptr; + 100 696987 : uintptr_t offset = (uintptr_t)ptr; 101 : - 102 696867 : offset = (offset + size - 1U) & ~(size - 1U); + 102 696987 : offset = (offset + size - 1U) & ~(size - 1U); 103 : - 104 696867 : return (void *)offset; + 104 696987 : return (void *)offset; 105 : } 106 : 107 : /* @@ -284,7 +284,7 @@ 222 : /* that use a weak memory model. To ensure that other processors */ 223 : /* see correctly the data written, we use a store-store memory */ 224 : /* barrier at the end of the asm code */ - 225 1365600 : asm volatile ("sfence" : : : "memory"); + 225 1365700 : asm volatile ("sfence" : : : "memory"); 226 : 227 : /* clobbers registers used in the asm code */ 228 : /* this is required because in the Windows ABI, */ diff --git a/cov/raid/intz.c.func-sort-c.html b/cov/raid/intz.c.func-sort-c.html index c6e0e60f..b79b344c 100644 --- a/cov/raid/intz.c.func-sort-c.html +++ b/cov/raid/intz.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/raid/intz.c.func.html b/cov/raid/intz.c.func.html index 09e4658c..081fcf8b 100644 --- a/cov/raid/intz.c.func.html +++ b/cov/raid/intz.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/raid/intz.c.gcov.html b/cov/raid/intz.c.gcov.html index 0d481bcf..68473b3c 100644 --- a/cov/raid/intz.c.gcov.html +++ b/cov/raid/intz.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 diff --git a/cov/raid/memory.c.func-sort-c.html b/cov/raid/memory.c.func-sort-c.html index b48d9a29..fd1f5017 100644 --- a/cov/raid/memory.c.func-sort-c.html +++ b/cov/raid/memory.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -61,7 +61,7 @@ raid_mtest_vector - 2583 + 2579 raid_malloc_align diff --git a/cov/raid/memory.c.func.html b/cov/raid/memory.c.func.html index 92b379d6..25536f02 100644 --- a/cov/raid/memory.c.func.html +++ b/cov/raid/memory.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -73,7 +73,7 @@ raid_mtest_vector - 2583 + 2579
diff --git a/cov/raid/memory.c.gcov.html b/cov/raid/memory.c.gcov.html index 784a9006..3830eccb 100644 --- a/cov/raid/memory.c.gcov.html +++ b/cov/raid/memory.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -94,7 +94,7 @@ 32 290 : offset = ((uintptr_t)ptr) % RAID_MALLOC_ALIGN; 33 : 34 290 : if (offset != 0) - 35 284 : ptr += RAID_MALLOC_ALIGN - offset; + 35 287 : ptr += RAID_MALLOC_ALIGN - offset; 36 : 37 290 : return ptr; 38 : } @@ -154,9 +154,9 @@ 92 : } 93 5 : } 94 : - 95 2583 : int raid_mtest_vector(int n, size_t size, void **vv) + 95 2579 : int raid_mtest_vector(int n, size_t size, void **vv) 96 : { - 97 2583 : unsigned char **v = (unsigned char **)vv; + 97 2579 : unsigned char **v = (unsigned char **)vv; 98 : int i; 99 : size_t j; 100 : unsigned k; @@ -164,39 +164,39 @@ 102 : unsigned char p; 103 : 104 : /* fill with 0 */ - 105 2583 : d = 0; - 106 5257 : for (i = 0; i < n; ++i) - 107 136288434 : for (j = 0; j < size; ++j) - 108 136285760 : v[i][j] = d; + 105 2579 : d = 0; + 106 5254 : for (i = 0; i < n; ++i) + 107 137567034 : for (j = 0; j < size; ++j) + 108 137564359 : v[i][j] = d; 109 : 110 : /* test with all the byte patterns */ - 111 661234 : for (k = 1; k < 256; ++k) { - 112 658651 : p = d; - 113 658651 : d = k; + 111 661244 : for (k = 1; k < 256; ++k) { + 112 658661 : p = d; + 113 658661 : d = k; 114 : 115 : /* forward fill */ - 116 1340760 : for (i = 0; i < n; ++i) { - 117 24240075844 : for (j = 0; j < size; ++j) { - 118 24239393735 : if (v[i][j] != p) { + 116 1340781 : for (i = 0; i < n; ++i) { + 117 24484944507 : for (j = 0; j < size; ++j) { + 118 24484262387 : if (v[i][j] != p) { 119 : /* LCOV_EXCL_START */ 120 : return -1; 121 : /* LCOV_EXCL_STOP */ 122 : } - 123 24239393729 : v[i][j] = d; + 123 24484262387 : v[i][j] = d; 124 : } 125 : } 126 : - 127 658645 : p = d; - 128 658645 : d = ~p; + 127 658661 : p = d; + 128 658661 : d = ~p; 129 : /* backward fill with complement */ - 130 1340755 : for (i = 0; i < n; ++i) { - 131 23878874802 : for (j = size; j > 0; --j) { - 132 23878192692 : if (v[i][j - 1] != p) { + 130 1340786 : for (i = 0; i < n; ++i) { + 131 24126962138 : for (j = size; j > 0; --j) { + 132 24126280013 : if (v[i][j - 1] != p) { 133 : /* LCOV_EXCL_START */ 134 : return -1; 135 : /* LCOV_EXCL_STOP */ 136 : } - 137 23878192698 : v[i][j - 1] = d; + 137 24126280017 : v[i][j - 1] = d; 138 : } 139 : } 140 : } diff --git a/cov/raid/module.c.func-sort-c.html b/cov/raid/module.c.func-sort-c.html index b469fbc8..3a1aa0e0 100644 --- a/cov/raid/module.c.func-sort-c.html +++ b/cov/raid/module.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 diff --git a/cov/raid/module.c.func.html b/cov/raid/module.c.func.html index 253ad344..a93ef0a6 100644 --- a/cov/raid/module.c.func.html +++ b/cov/raid/module.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 diff --git a/cov/raid/module.c.gcov.html b/cov/raid/module.c.gcov.html index e51fae4a..5769f207 100644 --- a/cov/raid/module.c.gcov.html +++ b/cov/raid/module.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 diff --git a/cov/raid/raid.c.func-sort-c.html b/cov/raid/raid.c.func-sort-c.html index e11a2ac4..77b192da 100644 --- a/cov/raid/raid.c.func-sort-c.html +++ b/cov/raid/raid.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 9 @@ -61,27 +61,27 @@ raid_gen - 1212640 + 1212946 raid_data - 217819 + 217853 raid_invert - 172870 + 172667 raid_delta_gen - 171518 + 171311 raid_rec1of1 - 104713 + 104953 raid_rec - 901 + 900 raid_mode diff --git a/cov/raid/raid.c.func.html b/cov/raid/raid.c.func.html index 8867f809..88ff8f70 100644 --- a/cov/raid/raid.c.func.html +++ b/cov/raid/raid.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 9 @@ -61,19 +61,19 @@ raid_data - 217819 + 217853 raid_delta_gen - 171518 + 171311 raid_gen - 1212640 + 1212946 raid_invert - 172870 + 172667 raid_mode @@ -81,11 +81,11 @@ raid_rec - 901 + 900 raid_rec1of1 - 104713 + 104953 raid_rec2of2_int8 diff --git a/cov/raid/raid.c.gcov.html b/cov/raid/raid.c.gcov.html index 2f1d943e..54d53596 100644 --- a/cov/raid/raid.c.gcov.html +++ b/cov/raid/raid.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 9 @@ -282,17 +282,17 @@ 220 : void (*raid_gen3_ptr)(int nd, size_t size, void **vv); 221 : void (*raid_genz_ptr)(int nd, size_t size, void **vv); 222 : - 223 1212640 : void raid_gen(int nd, int np, size_t size, void **v) + 223 1212946 : void raid_gen(int nd, int np, size_t size, void **v) 224 : { 225 : /* enforce limit on size */ - 226 1212640 : BUG_ON(size % 64 != 0); + 226 1212946 : BUG_ON(size % 64 != 0); 227 : 228 : /* enforce limit on number of failures */ - 229 1212640 : BUG_ON(np < 1); - 230 1212640 : BUG_ON(np > RAID_PARITY_MAX); + 229 1212946 : BUG_ON(np < 1); + 230 1212946 : BUG_ON(np > RAID_PARITY_MAX); 231 : - 232 1212640 : raid_gen_ptr[np - 1](nd, size, v); - 233 1212640 : } + 232 1212946 : raid_gen_ptr[np - 1](nd, size, v); + 233 1212946 : } 234 : 235 : /** 236 : * Inverts the square matrix M of size nxn into V. @@ -305,44 +305,44 @@ 243 : * @V Destination matrix where the result is put. 244 : * @n Number of rows and columns of the matrix. 245 : */ - 246 172870 : void raid_invert(uint8_t *M, uint8_t *V, int n) + 246 172667 : void raid_invert(uint8_t *M, uint8_t *V, int n) 247 : { 248 : int i, j, k; 249 : 250 : /* set the identity matrix in V */ - 251 798767 : for (i = 0; i < n; ++i) - 252 3222808 : for (j = 0; j < n; ++j) - 253 2596911 : V[i * n + j] = i == j; + 251 798158 : for (i = 0; i < n; ++i) + 252 3221590 : for (j = 0; j < n; ++j) + 253 2596099 : V[i * n + j] = i == j; 254 : 255 : /* for each element in the diagonal */ - 256 798767 : for (k = 0; k < n; ++k) { + 256 798158 : for (k = 0; k < n; ++k) { 257 : uint8_t f; 258 : 259 : /* the diagonal element cannot be 0 because */ 260 : /* we are inverting matrices with all the square */ 261 : /* submatrices not singular */ - 262 625897 : BUG_ON(M[k * n + k] == 0); + 262 625491 : BUG_ON(M[k * n + k] == 0); 263 : 264 : /* make the diagonal element to be 1 */ - 265 1251794 : f = inv(M[k * n + k]); - 266 3222808 : for (j = 0; j < n; ++j) { - 267 5193822 : M[k * n + j] = mul(f, M[k * n + j]); - 268 5193822 : V[k * n + j] = mul(f, V[k * n + j]); + 265 1250982 : f = inv(M[k * n + k]); + 266 3221590 : for (j = 0; j < n; ++j) { + 267 5192198 : M[k * n + j] = mul(f, M[k * n + j]); + 268 5192198 : V[k * n + j] = mul(f, V[k * n + j]); 269 : } 270 : 271 : /* make all the elements over and under the diagonal */ 272 : /* to be zero */ - 273 3222808 : for (i = 0; i < n; ++i) { - 274 2596911 : if (i == k) - 275 625897 : continue; - 276 1971014 : f = M[i * n + k]; - 277 11282400 : for (j = 0; j < n; ++j) { - 278 18622772 : M[i * n + j] ^= mul(f, M[k * n + j]); - 279 18622772 : V[i * n + j] ^= mul(f, V[k * n + j]); + 273 3221590 : for (i = 0; i < n; ++i) { + 274 2596099 : if (i == k) + 275 625491 : continue; + 276 1970608 : f = M[i * n + k]; + 277 11281182 : for (j = 0; j < n; ++j) { + 278 18621148 : M[i * n + j] ^= mul(f, M[k * n + j]); + 279 18621148 : V[i * n + j] ^= mul(f, V[k * n + j]); 280 : } 281 : } 282 : } - 283 172870 : } + 283 172667 : } 284 : 285 : /** 286 : * Computes the parity without the missing data blocks @@ -350,7 +350,7 @@ 288 : * 289 : * This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations. 290 : */ - 291 171518 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v) + 291 171311 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v) 292 : { 293 : void *p[RAID_PARITY_MAX]; 294 : void *pa[RAID_PARITY_MAX]; @@ -360,17 +360,17 @@ 298 : 299 : /* total number of parities we are going to process */ 300 : /* they are both the used and the unused ones */ - 301 171518 : np = ip[nr - 1] + 1; + 301 171311 : np = ip[nr - 1] + 1; 302 : 303 : /* latest missing data block */ - 304 171518 : latest = v[id[nr - 1]]; + 304 171311 : latest = v[id[nr - 1]]; 305 : 306 : /* setup pointers for delta computation */ - 307 873198 : for (i = 0, j = 0; i < np; ++i) { + 307 872577 : for (i = 0, j = 0; i < np; ++i) { 308 : /* keep a copy of the original parity vector */ - 309 701680 : p[i] = v[nd + i]; + 309 701266 : p[i] = v[nd + i]; 310 : - 311 701680 : if (ip[j] == i) { + 311 701266 : if (ip[j] == i) { 312 : /* 313 : * Set used parities to point to the missing 314 : * data blocks. @@ -381,19 +381,19 @@ 319 : 320 : /* the latest parity to use ends the for loop and */ 321 : /* then it cannot happen to process more of them */ - 322 605871 : BUG_ON(j >= nr); + 322 605461 : BUG_ON(j >= nr); 323 : 324 : /* buffer for missing data blocks */ - 325 605871 : pa[j] = v[id[j]]; + 325 605461 : pa[j] = v[id[j]]; 326 : 327 : /* set at zero the missing data blocks */ - 328 605871 : v[id[j]] = raid_zero_block; + 328 605461 : v[id[j]] = raid_zero_block; 329 : 330 : /* compute the parity over the missing data blocks */ - 331 605871 : v[nd + i] = pa[j]; + 331 605461 : v[nd + i] = pa[j]; 332 : 333 : /* check for the next used entry */ - 334 605871 : ++j; + 334 605461 : ++j; 335 : } else { 336 : /* 337 : * Unused parities are going to be rewritten with @@ -413,25 +413,25 @@ 351 : * multiple times and only the latest write will 352 : * contain the correct data. 353 : */ - 354 95809 : v[nd + i] = latest; + 354 95805 : v[nd + i] = latest; 355 : } 356 : } 357 : 358 : /* all the parities have to be processed */ - 359 171518 : BUG_ON(j != nr); + 359 171311 : BUG_ON(j != nr); 360 : 361 : /* recompute the parity, note that np may be smaller than the */ 362 : /* total number of parities available */ - 363 171518 : raid_gen(nd, np, size, v); + 363 171311 : raid_gen(nd, np, size, v); 364 : 365 : /* restore data buffers as before */ - 366 777389 : for (j = 0; j < nr; ++j) - 367 605871 : v[id[j]] = pa[j]; + 366 776772 : for (j = 0; j < nr; ++j) + 367 605461 : v[id[j]] = pa[j]; 368 : 369 : /* restore parity buffers as before */ - 370 873198 : for (i = 0; i < np; ++i) - 371 701680 : v[nd + i] = p[i]; - 372 171518 : } + 370 872577 : for (i = 0; i < np; ++i) + 371 701266 : v[nd + i] = p[i]; + 372 171311 : } 373 : 374 : /** 375 : * Recover failure of one data block for PAR1. @@ -444,29 +444,29 @@ 382 : * 383 : * Dx = Pd 384 : */ - 385 104713 : void raid_rec1of1(int *id, int nd, size_t size, void **v) + 385 104953 : void raid_rec1of1(int *id, int nd, size_t size, void **v) 386 : { 387 : void *p; 388 : void *pa; 389 : 390 : /* for PAR1 we can directly compute the missing block */ 391 : /* and we don't need to use the zero buffer */ - 392 104713 : p = v[nd]; - 393 104713 : pa = v[id[0]]; + 392 104953 : p = v[nd]; + 393 104953 : pa = v[id[0]]; 394 : 395 : /* use the parity as missing data block */ - 396 104713 : v[id[0]] = p; + 396 104953 : v[id[0]] = p; 397 : 398 : /* compute the parity over the missing data block */ - 399 104713 : v[nd] = pa; + 399 104953 : v[nd] = pa; 400 : 401 : /* compute */ - 402 104713 : raid_gen(nd, 1, size, v); + 402 104953 : raid_gen(nd, 1, size, v); 403 : 404 : /* restore as before */ - 405 104713 : v[id[0]] = pa; - 406 104713 : v[nd] = p; - 407 104713 : } + 405 104953 : v[id[0]] = pa; + 406 104953 : v[nd] = p; + 407 104953 : } 408 : 409 : /** 410 : * Recover failure of two data blocks for PAR2. @@ -554,97 +554,97 @@ 492 : void (*raid_rec_ptr[RAID_PARITY_MAX])( 493 : int nr, int *id, int *ip, int nd, size_t size, void **vv); 494 : - 495 901 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v) + 495 900 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v) 496 : { 497 : int nrd; /* number of data blocks to recover */ 498 : int nrp; /* number of parity blocks to recover */ 499 : 500 : /* enforce limit on size */ - 501 901 : BUG_ON(size % 64 != 0); + 501 900 : BUG_ON(size % 64 != 0); 502 : 503 : /* enforce limit on number of failures */ - 504 901 : BUG_ON(nr > np); - 505 901 : BUG_ON(np > RAID_PARITY_MAX); + 504 900 : BUG_ON(nr > np); + 505 900 : BUG_ON(np > RAID_PARITY_MAX); 506 : 507 : /* enforce order in index vector */ - 508 901 : BUG_ON(nr >= 2 && ir[0] >= ir[1]); - 509 901 : BUG_ON(nr >= 3 && ir[1] >= ir[2]); - 510 901 : BUG_ON(nr >= 4 && ir[2] >= ir[3]); - 511 901 : BUG_ON(nr >= 5 && ir[3] >= ir[4]); - 512 901 : BUG_ON(nr >= 6 && ir[4] >= ir[5]); + 508 900 : BUG_ON(nr >= 2 && ir[0] >= ir[1]); + 509 900 : BUG_ON(nr >= 3 && ir[1] >= ir[2]); + 510 900 : BUG_ON(nr >= 4 && ir[2] >= ir[3]); + 511 900 : BUG_ON(nr >= 5 && ir[3] >= ir[4]); + 512 900 : BUG_ON(nr >= 6 && ir[4] >= ir[5]); 513 : 514 : /* enforce limit on index vector */ - 515 901 : BUG_ON(nr > 0 && ir[nr-1] >= nd + np); + 515 900 : BUG_ON(nr > 0 && ir[nr-1] >= nd + np); 516 : 517 : /* count the number of data blocks to recover */ - 518 901 : nrd = 0; - 519 3607 : while (nrd < nr && ir[nrd] < nd) - 520 1805 : ++nrd; + 518 900 : nrd = 0; + 519 3603 : while (nrd < nr && ir[nrd] < nd) + 520 1803 : ++nrd; 521 : 522 : /* all the remaining are parity */ - 523 901 : nrp = nr - nrd; + 523 900 : nrp = nr - nrd; 524 : 525 : /* enforce limit on number of failures */ - 526 901 : BUG_ON(nrd > nd); - 527 901 : BUG_ON(nrp > np); + 526 900 : BUG_ON(nrd > nd); + 527 900 : BUG_ON(nrp > np); 528 : 529 : /* if failed data is present */ - 530 901 : if (nrd != 0) { + 530 900 : if (nrd != 0) { 531 : int ip[RAID_PARITY_MAX]; 532 : int i, j, k; 533 : 534 : /* setup the vector of parities to use */ - 535 6258 : for (i = 0, j = 0, k = 0; i < np; ++i) { - 536 5359 : if (j < nrp && ir[nrd + j] == nd + i) { + 535 6251 : for (i = 0, j = 0, k = 0; i < np; ++i) { + 536 5353 : if (j < nrp && ir[nrd + j] == nd + i) { 537 : /* this parity has to be recovered */ 538 22 : ++j; 539 : } else { 540 : /* this parity is used for recovering */ - 541 5337 : ip[k] = i; - 542 5337 : ++k; + 541 5331 : ip[k] = i; + 542 5331 : ++k; 543 : } 544 : } 545 : 546 : /* recover the nrd data blocks specified in ir[], */ 547 : /* using the first nrd parity in ip[] for recovering */ - 548 899 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v); + 548 898 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v); 549 : } 550 : 551 : /* recompute all the parities up to the last bad one */ - 552 901 : if (nrp != 0) + 552 900 : if (nrp != 0) 553 12 : raid_gen(nd, ir[nr - 1] - nd + 1, size, v); - 554 901 : } + 554 900 : } 555 : - 556 217819 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v) + 556 217853 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v) 557 : { 558 : /* enforce limit on size */ - 559 217819 : BUG_ON(size % 64 != 0); + 559 217853 : BUG_ON(size % 64 != 0); 560 : 561 : /* enforce limit on number of failures */ - 562 217819 : BUG_ON(nr > nd); - 563 217819 : BUG_ON(nr > RAID_PARITY_MAX); + 562 217853 : BUG_ON(nr > nd); + 563 217853 : BUG_ON(nr > RAID_PARITY_MAX); 564 : 565 : /* enforce order in index vector for data */ - 566 217819 : BUG_ON(nr >= 2 && id[0] >= id[1]); - 567 217819 : BUG_ON(nr >= 3 && id[1] >= id[2]); - 568 217819 : BUG_ON(nr >= 4 && id[2] >= id[3]); - 569 217819 : BUG_ON(nr >= 5 && id[3] >= id[4]); - 570 217819 : BUG_ON(nr >= 6 && id[4] >= id[5]); + 566 217853 : BUG_ON(nr >= 2 && id[0] >= id[1]); + 567 217853 : BUG_ON(nr >= 3 && id[1] >= id[2]); + 568 217853 : BUG_ON(nr >= 4 && id[2] >= id[3]); + 569 217853 : BUG_ON(nr >= 5 && id[3] >= id[4]); + 570 217853 : BUG_ON(nr >= 6 && id[4] >= id[5]); 571 : 572 : /* enforce limit on index vector for data */ - 573 217819 : BUG_ON(nr > 0 && id[nr-1] >= nd); + 573 217853 : BUG_ON(nr > 0 && id[nr-1] >= nd); 574 : 575 : /* enforce order in index vector for parity */ - 576 217819 : BUG_ON(nr >= 2 && ip[0] >= ip[1]); - 577 217819 : BUG_ON(nr >= 3 && ip[1] >= ip[2]); - 578 217819 : BUG_ON(nr >= 4 && ip[2] >= ip[3]); - 579 217819 : BUG_ON(nr >= 5 && ip[3] >= ip[4]); - 580 217819 : BUG_ON(nr >= 6 && ip[4] >= ip[5]); + 576 217853 : BUG_ON(nr >= 2 && ip[0] >= ip[1]); + 577 217853 : BUG_ON(nr >= 3 && ip[1] >= ip[2]); + 578 217853 : BUG_ON(nr >= 4 && ip[2] >= ip[3]); + 579 217853 : BUG_ON(nr >= 5 && ip[3] >= ip[4]); + 580 217853 : BUG_ON(nr >= 6 && ip[4] >= ip[5]); 581 : 582 : /* if failed data is present */ - 583 217819 : if (nr != 0) - 584 217817 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v); - 585 217819 : } + 583 217853 : if (nr != 0) + 584 217851 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v); + 585 217853 : } 586 : diff --git a/cov/raid/tag.c.func-sort-c.html b/cov/raid/tag.c.func-sort-c.html index b103e719..31c0d253 100644 --- a/cov/raid/tag.c.func-sort-c.html +++ b/cov/raid/tag.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 diff --git a/cov/raid/tag.c.func.html b/cov/raid/tag.c.func.html index 93261ea2..14aa49dc 100644 --- a/cov/raid/tag.c.func.html +++ b/cov/raid/tag.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 diff --git a/cov/raid/tag.c.gcov.html b/cov/raid/tag.c.gcov.html index bb65c21e..942fdb77 100644 --- a/cov/raid/tag.c.gcov.html +++ b/cov/raid/tag.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 diff --git a/cov/raid/test.c.func-sort-c.html b/cov/raid/test.c.func-sort-c.html index 4bb39850..98effa0b 100644 --- a/cov/raid/test.c.func-sort-c.html +++ b/cov/raid/test.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 diff --git a/cov/raid/test.c.func.html b/cov/raid/test.c.func.html index 89e4ad2c..7a09c565 100644 --- a/cov/raid/test.c.func.html +++ b/cov/raid/test.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 diff --git a/cov/raid/test.c.gcov.html b/cov/raid/test.c.gcov.html index eda1d7c4..6104fd17 100644 --- a/cov/raid/test.c.gcov.html +++ b/cov/raid/test.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 7 diff --git a/cov/raid/x86.c.func-sort-c.html b/cov/raid/x86.c.func-sort-c.html index f6f0d5a9..5c4222d3 100644 --- a/cov/raid/x86.c.func-sort-c.html +++ b/cov/raid/x86.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 14 @@ -61,19 +61,19 @@ raid_gen6_ssse3 - 549547 + 549666 raid_gen2_sse2 - 276700 + 276492 raid_gen1_sse2 - 272945 + 273337 raid_rec1_ssse3 - 114194 + 114430 raid_recX_ssse3 @@ -81,19 +81,19 @@ raid_gen5_ssse3 - 50257 + 50258 raid_rec2_ssse3 - 44409 + 44206 raid_gen4_ssse3 - 32611 + 32613 raid_gen3_ssse3 - 29450 + 29451 raid_recX_avx2 diff --git a/cov/raid/x86.c.func.html b/cov/raid/x86.c.func.html index 6a37a421..adc9e8a9 100644 --- a/cov/raid/x86.c.func.html +++ b/cov/raid/x86.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 14 @@ -65,7 +65,7 @@ raid_gen1_sse2 - 272945 + 273337 raid_gen2_avx2 @@ -73,23 +73,23 @@ raid_gen2_sse2 - 276700 + 276492 raid_gen3_ssse3 - 29450 + 29451 raid_gen4_ssse3 - 32611 + 32613 raid_gen5_ssse3 - 50257 + 50258 raid_gen6_ssse3 - 549547 + 549666 raid_rec1_avx2 @@ -97,7 +97,7 @@ raid_rec1_ssse3 - 114194 + 114430 raid_rec2_avx2 @@ -105,7 +105,7 @@ raid_rec2_ssse3 - 44409 + 44206 raid_recX_avx2 diff --git a/cov/raid/x86.c.gcov.html b/cov/raid/x86.c.gcov.html index 9f5fbebe..8835cf3b 100644 --- a/cov/raid/x86.c.gcov.html +++ b/cov/raid/x86.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 14 @@ -95,37 +95,37 @@ 33 : * cache block, and processing 128 bytes doesn't increase performance, and in 34 : * some cases it even decreases it. 35 : */ - 36 272945 : void raid_gen1_sse2(int nd, size_t size, void **vv) + 36 273337 : void raid_gen1_sse2(int nd, size_t size, void **vv) 37 : { - 38 272945 : uint8_t **v = (uint8_t **)vv; + 38 273337 : uint8_t **v = (uint8_t **)vv; 39 : uint8_t *p; 40 : int d, l; 41 : size_t i; 42 : - 43 272945 : l = nd - 1; - 44 272945 : p = v[nd]; + 43 273337 : l = nd - 1; + 44 273337 : p = v[nd]; 45 : 46 : raid_sse_begin(); 47 : - 48 5896669 : for (i = 0; i < size; i += 64) { - 49 5623724 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); - 50 5623724 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); - 51 5623724 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32])); - 52 5623724 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48])); - 53 36265668 : for (d = l - 1; d >= 0; --d) { - 54 30641944 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i])); - 55 30641944 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16])); - 56 30641944 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32])); - 57 30641944 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48])); + 48 5895173 : for (i = 0; i < size; i += 64) { + 49 5621836 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); + 50 5621836 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); + 51 5621836 : asm volatile ("movdqa %0,%%xmm2" : : "m" (v[l][i + 32])); + 52 5621836 : asm volatile ("movdqa %0,%%xmm3" : : "m" (v[l][i + 48])); + 53 36237956 : for (d = l - 1; d >= 0; --d) { + 54 30616120 : asm volatile ("pxor %0,%%xmm0" : : "m" (v[d][i])); + 55 30616120 : asm volatile ("pxor %0,%%xmm1" : : "m" (v[d][i + 16])); + 56 30616120 : asm volatile ("pxor %0,%%xmm2" : : "m" (v[d][i + 32])); + 57 30616120 : asm volatile ("pxor %0,%%xmm3" : : "m" (v[d][i + 48])); 58 : } - 59 5623724 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 60 5623724 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); - 61 5623724 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32])); - 62 5623724 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48])); + 59 5621836 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 60 5621836 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); + 61 5621836 : asm volatile ("movntdq %%xmm2,%0" : "=m" (p[i + 32])); + 62 5621836 : asm volatile ("movntdq %%xmm3,%0" : "=m" (p[i + 48])); 63 : } 64 : 65 : raid_sse_end(); - 66 272945 : } + 66 273337 : } 67 : #endif 68 : 69 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2) @@ -183,54 +183,54 @@ 121 : /* 122 : * GEN2 (RAID6 with powers of 2) SSE2 implementation 123 : */ - 124 276700 : void raid_gen2_sse2(int nd, size_t size, void **vv) + 124 276492 : void raid_gen2_sse2(int nd, size_t size, void **vv) 125 : { - 126 276700 : uint8_t **v = (uint8_t **)vv; + 126 276492 : uint8_t **v = (uint8_t **)vv; 127 : uint8_t *p; 128 : uint8_t *q; 129 : int d, l; 130 : size_t i; 131 : - 132 276700 : l = nd - 1; - 133 276700 : p = v[nd]; - 134 276700 : q = v[nd + 1]; + 132 276492 : l = nd - 1; + 133 276492 : p = v[nd]; + 134 276492 : q = v[nd + 1]; 135 : 136 : raid_sse_begin(); 137 : - 138 276700 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 138 276492 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 139 : - 140 11089428 : for (i = 0; i < size; i += 32) { - 141 10812728 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); - 142 10812728 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); - 143 10812728 : asm volatile ("movdqa %xmm0,%xmm2"); - 144 10812728 : asm volatile ("movdqa %xmm1,%xmm3"); - 145 68808904 : for (d = l - 1; d >= 0; --d) { - 146 57996176 : asm volatile ("pxor %xmm4,%xmm4"); - 147 57996176 : asm volatile ("pxor %xmm5,%xmm5"); - 148 57996176 : asm volatile ("pcmpgtb %xmm2,%xmm4"); - 149 57996176 : asm volatile ("pcmpgtb %xmm3,%xmm5"); - 150 57996176 : asm volatile ("paddb %xmm2,%xmm2"); - 151 57996176 : asm volatile ("paddb %xmm3,%xmm3"); - 152 57996176 : asm volatile ("pand %xmm7,%xmm4"); - 153 57996176 : asm volatile ("pand %xmm7,%xmm5"); - 154 57996176 : asm volatile ("pxor %xmm4,%xmm2"); - 155 57996176 : asm volatile ("pxor %xmm5,%xmm3"); + 140 11074404 : for (i = 0; i < size; i += 32) { + 141 10797912 : asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i])); + 142 10797912 : asm volatile ("movdqa %0,%%xmm1" : : "m" (v[l][i + 16])); + 143 10797912 : asm volatile ("movdqa %xmm0,%xmm2"); + 144 10797912 : asm volatile ("movdqa %xmm1,%xmm3"); + 145 68703624 : for (d = l - 1; d >= 0; --d) { + 146 57905712 : asm volatile ("pxor %xmm4,%xmm4"); + 147 57905712 : asm volatile ("pxor %xmm5,%xmm5"); + 148 57905712 : asm volatile ("pcmpgtb %xmm2,%xmm4"); + 149 57905712 : asm volatile ("pcmpgtb %xmm3,%xmm5"); + 150 57905712 : asm volatile ("paddb %xmm2,%xmm2"); + 151 57905712 : asm volatile ("paddb %xmm3,%xmm3"); + 152 57905712 : asm volatile ("pand %xmm7,%xmm4"); + 153 57905712 : asm volatile ("pand %xmm7,%xmm5"); + 154 57905712 : asm volatile ("pxor %xmm4,%xmm2"); + 155 57905712 : asm volatile ("pxor %xmm5,%xmm3"); 156 : - 157 57996176 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); - 158 57996176 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16])); - 159 57996176 : asm volatile ("pxor %xmm4,%xmm0"); - 160 57996176 : asm volatile ("pxor %xmm5,%xmm1"); - 161 57996176 : asm volatile ("pxor %xmm4,%xmm2"); - 162 57996176 : asm volatile ("pxor %xmm5,%xmm3"); + 157 57905712 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 158 57905712 : asm volatile ("movdqa %0,%%xmm5" : : "m" (v[d][i + 16])); + 159 57905712 : asm volatile ("pxor %xmm4,%xmm0"); + 160 57905712 : asm volatile ("pxor %xmm5,%xmm1"); + 161 57905712 : asm volatile ("pxor %xmm4,%xmm2"); + 162 57905712 : asm volatile ("pxor %xmm5,%xmm3"); 163 : } - 164 10812728 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 165 10812728 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); - 166 10812728 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i])); - 167 10812728 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16])); + 164 10797912 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 165 10797912 : asm volatile ("movntdq %%xmm1,%0" : "=m" (p[i + 16])); + 166 10797912 : asm volatile ("movntdq %%xmm2,%0" : "=m" (q[i])); + 167 10797912 : asm volatile ("movntdq %%xmm3,%0" : "=m" (q[i + 16])); 168 : } 169 : 170 : raid_sse_end(); - 171 276700 : } + 171 276492 : } 172 : #endif 173 : 174 : #if defined(CONFIG_X86) && defined(CONFIG_AVX2) @@ -370,93 +370,93 @@ 308 : /* 309 : * GEN3 (triple parity with Cauchy matrix) SSSE3 implementation 310 : */ - 311 29450 : void raid_gen3_ssse3(int nd, size_t size, void **vv) + 311 29451 : void raid_gen3_ssse3(int nd, size_t size, void **vv) 312 : { - 313 29450 : uint8_t **v = (uint8_t **)vv; + 313 29451 : uint8_t **v = (uint8_t **)vv; 314 : uint8_t *p; 315 : uint8_t *q; 316 : uint8_t *r; 317 : int d, l; 318 : size_t i; 319 : - 320 29450 : l = nd - 1; - 321 29450 : p = v[nd]; - 322 29450 : q = v[nd + 1]; - 323 29450 : r = v[nd + 2]; + 320 29451 : l = nd - 1; + 321 29451 : p = v[nd]; + 322 29451 : q = v[nd + 1]; + 323 29451 : r = v[nd + 2]; 324 : 325 : /* special case with only one data disk */ - 326 29450 : if (l == 0) { + 326 29451 : if (l == 0) { 327 4 : for (i = 0; i < 3; ++i) 328 3 : memcpy(v[1 + i], v[0], size); - 329 29451 : return; + 329 29452 : return; 330 : } 331 : 332 : raid_sse_begin(); 333 : 334 : /* generic case with at least two data disks */ - 335 29449 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0])); - 336 29449 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 335 29450 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfconst16.poly[0])); + 336 29450 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); 337 : - 338 4899161 : for (i = 0; i < size; i += 16) { + 338 4915546 : for (i = 0; i < size; i += 16) { 339 : /* last disk without the by two multiplication */ - 340 4869712 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 340 4886096 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 341 : - 342 4869712 : asm volatile ("movdqa %xmm4,%xmm0"); - 343 4869712 : asm volatile ("movdqa %xmm4,%xmm1"); + 342 4886096 : asm volatile ("movdqa %xmm4,%xmm0"); + 343 4886096 : asm volatile ("movdqa %xmm4,%xmm1"); 344 : - 345 4869712 : asm volatile ("movdqa %xmm4,%xmm5"); - 346 4869712 : asm volatile ("psrlw $4,%xmm5"); - 347 4869712 : asm volatile ("pand %xmm7,%xmm4"); - 348 4869712 : asm volatile ("pand %xmm7,%xmm5"); + 345 4886096 : asm volatile ("movdqa %xmm4,%xmm5"); + 346 4886096 : asm volatile ("psrlw $4,%xmm5"); + 347 4886096 : asm volatile ("pand %xmm7,%xmm4"); + 348 4886096 : asm volatile ("pand %xmm7,%xmm5"); 349 : - 350 4869712 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); - 351 4869712 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0])); - 352 4869712 : asm volatile ("pshufb %xmm4,%xmm2"); - 353 4869712 : asm volatile ("pshufb %xmm5,%xmm6"); - 354 4869712 : asm volatile ("pxor %xmm6,%xmm2"); + 350 4886096 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); + 351 4886096 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0])); + 352 4886096 : asm volatile ("pshufb %xmm4,%xmm2"); + 353 4886096 : asm volatile ("pshufb %xmm5,%xmm6"); + 354 4886096 : asm volatile ("pxor %xmm6,%xmm2"); 355 : 356 : /* intermediate disks */ - 357 30574256 : for (d = l - 1; d > 0; --d) { - 358 25704544 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 357 30688944 : for (d = l - 1; d > 0; --d) { + 358 25802848 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); 359 : - 360 25704544 : asm volatile ("pxor %xmm5,%xmm5"); - 361 25704544 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 362 25704544 : asm volatile ("paddb %xmm1,%xmm1"); - 363 25704544 : asm volatile ("pand %xmm3,%xmm5"); - 364 25704544 : asm volatile ("pxor %xmm5,%xmm1"); + 360 25802848 : asm volatile ("pxor %xmm5,%xmm5"); + 361 25802848 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 362 25802848 : asm volatile ("paddb %xmm1,%xmm1"); + 363 25802848 : asm volatile ("pand %xmm3,%xmm5"); + 364 25802848 : asm volatile ("pxor %xmm5,%xmm1"); 365 : - 366 25704544 : asm volatile ("pxor %xmm4,%xmm0"); - 367 25704544 : asm volatile ("pxor %xmm4,%xmm1"); + 366 25802848 : asm volatile ("pxor %xmm4,%xmm0"); + 367 25802848 : asm volatile ("pxor %xmm4,%xmm1"); 368 : - 369 25704544 : asm volatile ("movdqa %xmm4,%xmm5"); - 370 25704544 : asm volatile ("psrlw $4,%xmm5"); - 371 25704544 : asm volatile ("pand %xmm7,%xmm4"); - 372 25704544 : asm volatile ("pand %xmm7,%xmm5"); + 369 25802848 : asm volatile ("movdqa %xmm4,%xmm5"); + 370 25802848 : asm volatile ("psrlw $4,%xmm5"); + 371 25802848 : asm volatile ("pand %xmm7,%xmm4"); + 372 25802848 : asm volatile ("pand %xmm7,%xmm5"); 373 : - 374 25704544 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 375 25704544 : asm volatile ("pshufb %xmm4,%xmm6"); - 376 25704544 : asm volatile ("pxor %xmm6,%xmm2"); - 377 25704544 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0])); - 378 25704544 : asm volatile ("pshufb %xmm5,%xmm6"); - 379 25704544 : asm volatile ("pxor %xmm6,%xmm2"); + 374 25802848 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 375 25802848 : asm volatile ("pshufb %xmm4,%xmm6"); + 376 25802848 : asm volatile ("pxor %xmm6,%xmm2"); + 377 25802848 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0])); + 378 25802848 : asm volatile ("pshufb %xmm5,%xmm6"); + 379 25802848 : asm volatile ("pxor %xmm6,%xmm2"); 380 : } 381 : 382 : /* first disk with all coefficients at 1 */ - 383 4869712 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 383 4886096 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); 384 : - 385 4869712 : asm volatile ("pxor %xmm5,%xmm5"); - 386 4869712 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 387 4869712 : asm volatile ("paddb %xmm1,%xmm1"); - 388 4869712 : asm volatile ("pand %xmm3,%xmm5"); - 389 4869712 : asm volatile ("pxor %xmm5,%xmm1"); + 385 4886096 : asm volatile ("pxor %xmm5,%xmm5"); + 386 4886096 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 387 4886096 : asm volatile ("paddb %xmm1,%xmm1"); + 388 4886096 : asm volatile ("pand %xmm3,%xmm5"); + 389 4886096 : asm volatile ("pxor %xmm5,%xmm1"); 390 : - 391 4869712 : asm volatile ("pxor %xmm4,%xmm0"); - 392 4869712 : asm volatile ("pxor %xmm4,%xmm1"); - 393 4869712 : asm volatile ("pxor %xmm4,%xmm2"); + 391 4886096 : asm volatile ("pxor %xmm4,%xmm0"); + 392 4886096 : asm volatile ("pxor %xmm4,%xmm1"); + 393 4886096 : asm volatile ("pxor %xmm4,%xmm2"); 394 : - 395 4869712 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 396 4869712 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); - 397 4869712 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); + 395 4886096 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 396 4886096 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); + 397 4886096 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); 398 : } 399 : 400 : raid_sse_end(); @@ -741,9 +741,9 @@ 679 : /* 680 : * GEN4 (quad parity with Cauchy matrix) SSSE3 implementation 681 : */ - 682 32611 : void raid_gen4_ssse3(int nd, size_t size, void **vv) + 682 32613 : void raid_gen4_ssse3(int nd, size_t size, void **vv) 683 : { - 684 32611 : uint8_t **v = (uint8_t **)vv; + 684 32613 : uint8_t **v = (uint8_t **)vv; 685 : uint8_t *p; 686 : uint8_t *q; 687 : uint8_t *r; @@ -751,102 +751,102 @@ 689 : int d, l; 690 : size_t i; 691 : - 692 32611 : l = nd - 1; - 693 32611 : p = v[nd]; - 694 32611 : q = v[nd + 1]; - 695 32611 : r = v[nd + 2]; - 696 32611 : s = v[nd + 3]; + 692 32613 : l = nd - 1; + 693 32613 : p = v[nd]; + 694 32613 : q = v[nd + 1]; + 695 32613 : r = v[nd + 2]; + 696 32613 : s = v[nd + 3]; 697 : 698 : /* special case with only one data disk */ - 699 32611 : if (l == 0) { + 699 32613 : if (l == 0) { 700 5 : for (i = 0; i < 4; ++i) 701 4 : memcpy(v[1 + i], v[0], size); - 702 32612 : return; + 702 32614 : return; 703 : } 704 : 705 : raid_sse_begin(); 706 : 707 : /* generic case with at least two data disks */ - 708 3344034 : for (i = 0; i < size; i += 16) { + 708 3376804 : for (i = 0; i < size; i += 16) { 709 : /* last disk without the by two multiplication */ - 710 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 711 3311424 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 710 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 711 3344192 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 712 : - 713 3311424 : asm volatile ("movdqa %xmm4,%xmm0"); - 714 3311424 : asm volatile ("movdqa %xmm4,%xmm1"); + 713 3344192 : asm volatile ("movdqa %xmm4,%xmm0"); + 714 3344192 : asm volatile ("movdqa %xmm4,%xmm1"); 715 : - 716 3311424 : asm volatile ("movdqa %xmm4,%xmm5"); - 717 3311424 : asm volatile ("psrlw $4,%xmm5"); - 718 3311424 : asm volatile ("pand %xmm7,%xmm4"); - 719 3311424 : asm volatile ("pand %xmm7,%xmm5"); + 716 3344192 : asm volatile ("movdqa %xmm4,%xmm5"); + 717 3344192 : asm volatile ("psrlw $4,%xmm5"); + 718 3344192 : asm volatile ("pand %xmm7,%xmm4"); + 719 3344192 : asm volatile ("pand %xmm7,%xmm5"); 720 : - 721 3311424 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); - 722 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); - 723 3311424 : asm volatile ("pshufb %xmm4,%xmm2"); - 724 3311424 : asm volatile ("pshufb %xmm5,%xmm7"); - 725 3311424 : asm volatile ("pxor %xmm7,%xmm2"); + 721 3344192 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0])); + 722 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); + 723 3344192 : asm volatile ("pshufb %xmm4,%xmm2"); + 724 3344192 : asm volatile ("pshufb %xmm5,%xmm7"); + 725 3344192 : asm volatile ("pxor %xmm7,%xmm2"); 726 : - 727 3311424 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0])); - 728 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); - 729 3311424 : asm volatile ("pshufb %xmm4,%xmm3"); - 730 3311424 : asm volatile ("pshufb %xmm5,%xmm7"); - 731 3311424 : asm volatile ("pxor %xmm7,%xmm3"); + 727 3344192 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0])); + 728 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); + 729 3344192 : asm volatile ("pshufb %xmm4,%xmm3"); + 730 3344192 : asm volatile ("pshufb %xmm5,%xmm7"); + 731 3344192 : asm volatile ("pxor %xmm7,%xmm3"); 732 : 733 : /* intermediate disks */ - 734 19816832 : for (d = l - 1; d > 0; --d) { - 735 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); - 736 16505408 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 734 20046208 : for (d = l - 1; d > 0; --d) { + 735 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 736 16702016 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); 737 : - 738 16505408 : asm volatile ("pxor %xmm5,%xmm5"); - 739 16505408 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 740 16505408 : asm volatile ("paddb %xmm1,%xmm1"); - 741 16505408 : asm volatile ("pand %xmm7,%xmm5"); - 742 16505408 : asm volatile ("pxor %xmm5,%xmm1"); + 738 16702016 : asm volatile ("pxor %xmm5,%xmm5"); + 739 16702016 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 740 16702016 : asm volatile ("paddb %xmm1,%xmm1"); + 741 16702016 : asm volatile ("pand %xmm7,%xmm5"); + 742 16702016 : asm volatile ("pxor %xmm5,%xmm1"); 743 : - 744 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 744 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); 745 : - 746 16505408 : asm volatile ("pxor %xmm4,%xmm0"); - 747 16505408 : asm volatile ("pxor %xmm4,%xmm1"); + 746 16702016 : asm volatile ("pxor %xmm4,%xmm0"); + 747 16702016 : asm volatile ("pxor %xmm4,%xmm1"); 748 : - 749 16505408 : asm volatile ("movdqa %xmm4,%xmm5"); - 750 16505408 : asm volatile ("psrlw $4,%xmm5"); - 751 16505408 : asm volatile ("pand %xmm7,%xmm4"); - 752 16505408 : asm volatile ("pand %xmm7,%xmm5"); + 749 16702016 : asm volatile ("movdqa %xmm4,%xmm5"); + 750 16702016 : asm volatile ("psrlw $4,%xmm5"); + 751 16702016 : asm volatile ("pand %xmm7,%xmm4"); + 752 16702016 : asm volatile ("pand %xmm7,%xmm5"); 753 : - 754 16505408 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 755 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); - 756 16505408 : asm volatile ("pshufb %xmm4,%xmm6"); - 757 16505408 : asm volatile ("pshufb %xmm5,%xmm7"); - 758 16505408 : asm volatile ("pxor %xmm6,%xmm2"); - 759 16505408 : asm volatile ("pxor %xmm7,%xmm2"); + 754 16702016 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 755 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); + 756 16702016 : asm volatile ("pshufb %xmm4,%xmm6"); + 757 16702016 : asm volatile ("pshufb %xmm5,%xmm7"); + 758 16702016 : asm volatile ("pxor %xmm6,%xmm2"); + 759 16702016 : asm volatile ("pxor %xmm7,%xmm2"); 760 : - 761 16505408 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); - 762 16505408 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); - 763 16505408 : asm volatile ("pshufb %xmm4,%xmm6"); - 764 16505408 : asm volatile ("pshufb %xmm5,%xmm7"); - 765 16505408 : asm volatile ("pxor %xmm6,%xmm3"); - 766 16505408 : asm volatile ("pxor %xmm7,%xmm3"); + 761 16702016 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); + 762 16702016 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); + 763 16702016 : asm volatile ("pshufb %xmm4,%xmm6"); + 764 16702016 : asm volatile ("pshufb %xmm5,%xmm7"); + 765 16702016 : asm volatile ("pxor %xmm6,%xmm3"); + 766 16702016 : asm volatile ("pxor %xmm7,%xmm3"); 767 : } 768 : 769 : /* first disk with all coefficients at 1 */ - 770 3311424 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); - 771 3311424 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 770 3344192 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 771 3344192 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); 772 : - 773 3311424 : asm volatile ("pxor %xmm5,%xmm5"); - 774 3311424 : asm volatile ("pcmpgtb %xmm1,%xmm5"); - 775 3311424 : asm volatile ("paddb %xmm1,%xmm1"); - 776 3311424 : asm volatile ("pand %xmm7,%xmm5"); - 777 3311424 : asm volatile ("pxor %xmm5,%xmm1"); + 773 3344192 : asm volatile ("pxor %xmm5,%xmm5"); + 774 3344192 : asm volatile ("pcmpgtb %xmm1,%xmm5"); + 775 3344192 : asm volatile ("paddb %xmm1,%xmm1"); + 776 3344192 : asm volatile ("pand %xmm7,%xmm5"); + 777 3344192 : asm volatile ("pxor %xmm5,%xmm1"); 778 : - 779 3311424 : asm volatile ("pxor %xmm4,%xmm0"); - 780 3311424 : asm volatile ("pxor %xmm4,%xmm1"); - 781 3311424 : asm volatile ("pxor %xmm4,%xmm2"); - 782 3311424 : asm volatile ("pxor %xmm4,%xmm3"); + 779 3344192 : asm volatile ("pxor %xmm4,%xmm0"); + 780 3344192 : asm volatile ("pxor %xmm4,%xmm1"); + 781 3344192 : asm volatile ("pxor %xmm4,%xmm2"); + 782 3344192 : asm volatile ("pxor %xmm4,%xmm3"); 783 : - 784 3311424 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); - 785 3311424 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); - 786 3311424 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); - 787 3311424 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i])); + 784 3344192 : asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i])); + 785 3344192 : asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i])); + 786 3344192 : asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i])); + 787 3344192 : asm volatile ("movntdq %%xmm3,%0" : "=m" (s[i])); 788 : } 789 : 790 : raid_sse_end(); @@ -1191,9 +1191,9 @@ 1129 : /* 1130 : * GEN5 (penta parity with Cauchy matrix) SSSE3 implementation 1131 : */ - 1132 50257 : void raid_gen5_ssse3(int nd, size_t size, void **vv) + 1132 50258 : void raid_gen5_ssse3(int nd, size_t size, void **vv) 1133 : { - 1134 50257 : uint8_t **v = (uint8_t **)vv; + 1134 50258 : uint8_t **v = (uint8_t **)vv; 1135 : uint8_t *p; 1136 : uint8_t *q; 1137 : uint8_t *r; @@ -1202,122 +1202,122 @@ 1140 : int d, l; 1141 : size_t i; 1142 : uint8_t buffer[16+16]; - 1143 50257 : uint8_t *pd = __align_ptr(buffer, 16); + 1143 50258 : uint8_t *pd = __align_ptr(buffer, 16); 1144 : - 1145 50257 : l = nd - 1; - 1146 50257 : p = v[nd]; - 1147 50257 : q = v[nd + 1]; - 1148 50257 : r = v[nd + 2]; - 1149 50257 : s = v[nd + 3]; - 1150 50257 : t = v[nd + 4]; + 1145 50258 : l = nd - 1; + 1146 50258 : p = v[nd]; + 1147 50258 : q = v[nd + 1]; + 1148 50258 : r = v[nd + 2]; + 1149 50258 : s = v[nd + 3]; + 1150 50258 : t = v[nd + 4]; 1151 : 1152 : /* special case with only one data disk */ - 1153 50257 : if (l == 0) { + 1153 50258 : if (l == 0) { 1154 6 : for (i = 0; i < 5; ++i) 1155 5 : memcpy(v[1 + i], v[0], size); - 1156 50258 : return; + 1156 50259 : return; 1157 : } 1158 : 1159 : raid_sse_begin(); 1160 : 1161 : /* generic case with at least two data disks */ - 1162 3928032 : for (i = 0; i < size; i += 16) { + 1162 3944417 : for (i = 0; i < size; i += 16) { 1163 : /* last disk without the by two multiplication */ - 1164 3877776 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 1164 3894160 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 1165 : - 1166 3877776 : asm volatile ("movdqa %xmm4,%xmm0"); - 1167 3877776 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); + 1166 3894160 : asm volatile ("movdqa %xmm4,%xmm0"); + 1167 3894160 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); 1168 : - 1169 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1170 3877776 : asm volatile ("movdqa %xmm4,%xmm5"); - 1171 3877776 : asm volatile ("psrlw $4,%xmm5"); - 1172 3877776 : asm volatile ("pand %xmm7,%xmm4"); - 1173 3877776 : asm volatile ("pand %xmm7,%xmm5"); + 1169 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1170 3894160 : asm volatile ("movdqa %xmm4,%xmm5"); + 1171 3894160 : asm volatile ("psrlw $4,%xmm5"); + 1172 3894160 : asm volatile ("pand %xmm7,%xmm4"); + 1173 3894160 : asm volatile ("pand %xmm7,%xmm5"); 1174 : - 1175 3877776 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0])); - 1176 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); - 1177 3877776 : asm volatile ("pshufb %xmm4,%xmm1"); - 1178 3877776 : asm volatile ("pshufb %xmm5,%xmm7"); - 1179 3877776 : asm volatile ("pxor %xmm7,%xmm1"); + 1175 3894160 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0])); + 1176 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); + 1177 3894160 : asm volatile ("pshufb %xmm4,%xmm1"); + 1178 3894160 : asm volatile ("pshufb %xmm5,%xmm7"); + 1179 3894160 : asm volatile ("pxor %xmm7,%xmm1"); 1180 : - 1181 3877776 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0])); - 1182 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); - 1183 3877776 : asm volatile ("pshufb %xmm4,%xmm2"); - 1184 3877776 : asm volatile ("pshufb %xmm5,%xmm7"); - 1185 3877776 : asm volatile ("pxor %xmm7,%xmm2"); + 1181 3894160 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0])); + 1182 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); + 1183 3894160 : asm volatile ("pshufb %xmm4,%xmm2"); + 1184 3894160 : asm volatile ("pshufb %xmm5,%xmm7"); + 1185 3894160 : asm volatile ("pxor %xmm7,%xmm2"); 1186 : - 1187 3877776 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0])); - 1188 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); - 1189 3877776 : asm volatile ("pshufb %xmm4,%xmm3"); - 1190 3877776 : asm volatile ("pshufb %xmm5,%xmm7"); - 1191 3877776 : asm volatile ("pxor %xmm7,%xmm3"); + 1187 3894160 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0])); + 1188 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); + 1189 3894160 : asm volatile ("pshufb %xmm4,%xmm3"); + 1190 3894160 : asm volatile ("pshufb %xmm5,%xmm7"); + 1191 3894160 : asm volatile ("pxor %xmm7,%xmm3"); 1192 : 1193 : /* intermediate disks */ - 1194 23251312 : for (d = l - 1; d > 0; --d) { - 1195 19373536 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); - 1196 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); - 1197 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1194 23366000 : for (d = l - 1; d > 0; --d) { + 1195 19471840 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 1196 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); + 1197 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1198 : - 1199 19373536 : asm volatile ("pxor %xmm5,%xmm5"); - 1200 19373536 : asm volatile ("pcmpgtb %xmm0,%xmm5"); - 1201 19373536 : asm volatile ("paddb %xmm0,%xmm0"); - 1202 19373536 : asm volatile ("pand %xmm7,%xmm5"); - 1203 19373536 : asm volatile ("pxor %xmm5,%xmm0"); + 1199 19471840 : asm volatile ("pxor %xmm5,%xmm5"); + 1200 19471840 : asm volatile ("pcmpgtb %xmm0,%xmm5"); + 1201 19471840 : asm volatile ("paddb %xmm0,%xmm0"); + 1202 19471840 : asm volatile ("pand %xmm7,%xmm5"); + 1203 19471840 : asm volatile ("pxor %xmm5,%xmm0"); 1204 : - 1205 19373536 : asm volatile ("pxor %xmm4,%xmm0"); - 1206 19373536 : asm volatile ("pxor %xmm4,%xmm6"); - 1207 19373536 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0])); + 1205 19471840 : asm volatile ("pxor %xmm4,%xmm0"); + 1206 19471840 : asm volatile ("pxor %xmm4,%xmm6"); + 1207 19471840 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[0])); 1208 : - 1209 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1210 19373536 : asm volatile ("movdqa %xmm4,%xmm5"); - 1211 19373536 : asm volatile ("psrlw $4,%xmm5"); - 1212 19373536 : asm volatile ("pand %xmm7,%xmm4"); - 1213 19373536 : asm volatile ("pand %xmm7,%xmm5"); + 1209 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1210 19471840 : asm volatile ("movdqa %xmm4,%xmm5"); + 1211 19471840 : asm volatile ("psrlw $4,%xmm5"); + 1212 19471840 : asm volatile ("pand %xmm7,%xmm4"); + 1213 19471840 : asm volatile ("pand %xmm7,%xmm5"); 1214 : - 1215 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 1216 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); - 1217 19373536 : asm volatile ("pshufb %xmm4,%xmm6"); - 1218 19373536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1219 19373536 : asm volatile ("pxor %xmm6,%xmm1"); - 1220 19373536 : asm volatile ("pxor %xmm7,%xmm1"); + 1215 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 1216 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); + 1217 19471840 : asm volatile ("pshufb %xmm4,%xmm6"); + 1218 19471840 : asm volatile ("pshufb %xmm5,%xmm7"); + 1219 19471840 : asm volatile ("pxor %xmm6,%xmm1"); + 1220 19471840 : asm volatile ("pxor %xmm7,%xmm1"); 1221 : - 1222 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); - 1223 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); - 1224 19373536 : asm volatile ("pshufb %xmm4,%xmm6"); - 1225 19373536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1226 19373536 : asm volatile ("pxor %xmm6,%xmm2"); - 1227 19373536 : asm volatile ("pxor %xmm7,%xmm2"); + 1222 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); + 1223 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); + 1224 19471840 : asm volatile ("pshufb %xmm4,%xmm6"); + 1225 19471840 : asm volatile ("pshufb %xmm5,%xmm7"); + 1226 19471840 : asm volatile ("pxor %xmm6,%xmm2"); + 1227 19471840 : asm volatile ("pxor %xmm7,%xmm2"); 1228 : - 1229 19373536 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); - 1230 19373536 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); - 1231 19373536 : asm volatile ("pshufb %xmm4,%xmm6"); - 1232 19373536 : asm volatile ("pshufb %xmm5,%xmm7"); - 1233 19373536 : asm volatile ("pxor %xmm6,%xmm3"); - 1234 19373536 : asm volatile ("pxor %xmm7,%xmm3"); + 1229 19471840 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); + 1230 19471840 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); + 1231 19471840 : asm volatile ("pshufb %xmm4,%xmm6"); + 1232 19471840 : asm volatile ("pshufb %xmm5,%xmm7"); + 1233 19471840 : asm volatile ("pxor %xmm6,%xmm3"); + 1234 19471840 : asm volatile ("pxor %xmm7,%xmm3"); 1235 : } 1236 : 1237 : /* first disk with all coefficients at 1 */ - 1238 3877776 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); - 1239 3877776 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); - 1240 3877776 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1238 3894160 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 1239 3894160 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[0])); + 1240 3894160 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1241 : - 1242 3877776 : asm volatile ("pxor %xmm5,%xmm5"); - 1243 3877776 : asm volatile ("pcmpgtb %xmm0,%xmm5"); - 1244 3877776 : asm volatile ("paddb %xmm0,%xmm0"); - 1245 3877776 : asm volatile ("pand %xmm7,%xmm5"); - 1246 3877776 : asm volatile ("pxor %xmm5,%xmm0"); + 1242 3894160 : asm volatile ("pxor %xmm5,%xmm5"); + 1243 3894160 : asm volatile ("pcmpgtb %xmm0,%xmm5"); + 1244 3894160 : asm volatile ("paddb %xmm0,%xmm0"); + 1245 3894160 : asm volatile ("pand %xmm7,%xmm5"); + 1246 3894160 : asm volatile ("pxor %xmm5,%xmm0"); 1247 : - 1248 3877776 : asm volatile ("pxor %xmm4,%xmm0"); - 1249 3877776 : asm volatile ("pxor %xmm4,%xmm1"); - 1250 3877776 : asm volatile ("pxor %xmm4,%xmm2"); - 1251 3877776 : asm volatile ("pxor %xmm4,%xmm3"); - 1252 3877776 : asm volatile ("pxor %xmm4,%xmm6"); + 1248 3894160 : asm volatile ("pxor %xmm4,%xmm0"); + 1249 3894160 : asm volatile ("pxor %xmm4,%xmm1"); + 1250 3894160 : asm volatile ("pxor %xmm4,%xmm2"); + 1251 3894160 : asm volatile ("pxor %xmm4,%xmm3"); + 1252 3894160 : asm volatile ("pxor %xmm4,%xmm6"); 1253 : - 1254 3877776 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i])); - 1255 3877776 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i])); - 1256 3877776 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i])); - 1257 3877776 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i])); - 1258 3877776 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i])); + 1254 3894160 : asm volatile ("movntdq %%xmm6,%0" : "=m" (p[i])); + 1255 3894160 : asm volatile ("movntdq %%xmm0,%0" : "=m" (q[i])); + 1256 3894160 : asm volatile ("movntdq %%xmm1,%0" : "=m" (r[i])); + 1257 3894160 : asm volatile ("movntdq %%xmm2,%0" : "=m" (s[i])); + 1258 3894160 : asm volatile ("movntdq %%xmm3,%0" : "=m" (t[i])); 1259 : } 1260 : 1261 : raid_sse_end(); @@ -1591,9 +1591,9 @@ 1529 : /* 1530 : * GEN6 (hexa parity with Cauchy matrix) SSSE3 implementation 1531 : */ - 1532 549547 : void raid_gen6_ssse3(int nd, size_t size, void **vv) + 1532 549666 : void raid_gen6_ssse3(int nd, size_t size, void **vv) 1533 : { - 1534 549547 : uint8_t **v = (uint8_t **)vv; + 1534 549666 : uint8_t **v = (uint8_t **)vv; 1535 : uint8_t *p; 1536 : uint8_t *q; 1537 : uint8_t *r; @@ -1603,142 +1603,142 @@ 1541 : int d, l; 1542 : size_t i; 1543 : uint8_t buffer[2*16+16]; - 1544 549547 : uint8_t *pd = __align_ptr(buffer, 16); + 1544 549666 : uint8_t *pd = __align_ptr(buffer, 16); 1545 : - 1546 549547 : l = nd - 1; - 1547 549547 : p = v[nd]; - 1548 549547 : q = v[nd + 1]; - 1549 549547 : r = v[nd + 2]; - 1550 549547 : s = v[nd + 3]; - 1551 549547 : t = v[nd + 4]; - 1552 549547 : u = v[nd + 5]; + 1546 549666 : l = nd - 1; + 1547 549666 : p = v[nd]; + 1548 549666 : q = v[nd + 1]; + 1549 549666 : r = v[nd + 2]; + 1550 549666 : s = v[nd + 3]; + 1551 549666 : t = v[nd + 4]; + 1552 549666 : u = v[nd + 5]; 1553 : 1554 : /* special case with only one data disk */ - 1555 549547 : if (l == 0) { + 1555 549666 : if (l == 0) { 1556 7 : for (i = 0; i < 6; ++i) 1557 6 : memcpy(v[1 + i], v[0], size); - 1558 549548 : return; + 1558 549667 : return; 1559 : } 1560 : 1561 : raid_sse_begin(); 1562 : 1563 : /* generic case with at least two data disks */ - 1564 35147130 : for (i = 0; i < size; i += 16) { + 1564 35154865 : for (i = 0; i < size; i += 16) { 1565 : /* last disk without the by two multiplication */ - 1566 34597584 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); + 1566 34605200 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[l][i])); 1567 : - 1568 34597584 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); - 1569 34597584 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16])); + 1568 34605200 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[0])); + 1569 34605200 : asm volatile ("movdqa %%xmm4,%0" : "=m" (pd[16])); 1570 : - 1571 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1572 34597584 : asm volatile ("movdqa %xmm4,%xmm5"); - 1573 34597584 : asm volatile ("psrlw $4,%xmm5"); - 1574 34597584 : asm volatile ("pand %xmm7,%xmm4"); - 1575 34597584 : asm volatile ("pand %xmm7,%xmm5"); + 1571 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1572 34605200 : asm volatile ("movdqa %xmm4,%xmm5"); + 1573 34605200 : asm volatile ("psrlw $4,%xmm5"); + 1574 34605200 : asm volatile ("pand %xmm7,%xmm4"); + 1575 34605200 : asm volatile ("pand %xmm7,%xmm5"); 1576 : - 1577 34597584 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0])); - 1578 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); - 1579 34597584 : asm volatile ("pshufb %xmm4,%xmm0"); - 1580 34597584 : asm volatile ("pshufb %xmm5,%xmm7"); - 1581 34597584 : asm volatile ("pxor %xmm7,%xmm0"); + 1577 34605200 : asm volatile ("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0])); + 1578 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0])); + 1579 34605200 : asm volatile ("pshufb %xmm4,%xmm0"); + 1580 34605200 : asm volatile ("pshufb %xmm5,%xmm7"); + 1581 34605200 : asm volatile ("pxor %xmm7,%xmm0"); 1582 : - 1583 34597584 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0])); - 1584 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); - 1585 34597584 : asm volatile ("pshufb %xmm4,%xmm1"); - 1586 34597584 : asm volatile ("pshufb %xmm5,%xmm7"); - 1587 34597584 : asm volatile ("pxor %xmm7,%xmm1"); + 1583 34605200 : asm volatile ("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0])); + 1584 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0])); + 1585 34605200 : asm volatile ("pshufb %xmm4,%xmm1"); + 1586 34605200 : asm volatile ("pshufb %xmm5,%xmm7"); + 1587 34605200 : asm volatile ("pxor %xmm7,%xmm1"); 1588 : - 1589 34597584 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0])); - 1590 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); - 1591 34597584 : asm volatile ("pshufb %xmm4,%xmm2"); - 1592 34597584 : asm volatile ("pshufb %xmm5,%xmm7"); - 1593 34597584 : asm volatile ("pxor %xmm7,%xmm2"); + 1589 34605200 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0])); + 1590 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0])); + 1591 34605200 : asm volatile ("pshufb %xmm4,%xmm2"); + 1592 34605200 : asm volatile ("pshufb %xmm5,%xmm7"); + 1593 34605200 : asm volatile ("pxor %xmm7,%xmm2"); 1594 : - 1595 34597584 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0])); - 1596 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0])); - 1597 34597584 : asm volatile ("pshufb %xmm4,%xmm3"); - 1598 34597584 : asm volatile ("pshufb %xmm5,%xmm7"); - 1599 34597584 : asm volatile ("pxor %xmm7,%xmm3"); + 1595 34605200 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0])); + 1596 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0])); + 1597 34605200 : asm volatile ("pshufb %xmm4,%xmm3"); + 1598 34605200 : asm volatile ("pshufb %xmm5,%xmm7"); + 1599 34605200 : asm volatile ("pxor %xmm7,%xmm3"); 1600 : 1601 : /* intermediate disks */ - 1602 178992816 : for (d = l - 1; d > 0; --d) { - 1603 144395232 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); - 1604 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); - 1605 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1602 179030896 : for (d = l - 1; d > 0; --d) { + 1603 144425696 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); + 1604 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); + 1605 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1606 : - 1607 144395232 : asm volatile ("pxor %xmm4,%xmm4"); - 1608 144395232 : asm volatile ("pcmpgtb %xmm6,%xmm4"); - 1609 144395232 : asm volatile ("paddb %xmm6,%xmm6"); - 1610 144395232 : asm volatile ("pand %xmm7,%xmm4"); - 1611 144395232 : asm volatile ("pxor %xmm4,%xmm6"); + 1607 144425696 : asm volatile ("pxor %xmm4,%xmm4"); + 1608 144425696 : asm volatile ("pcmpgtb %xmm6,%xmm4"); + 1609 144425696 : asm volatile ("paddb %xmm6,%xmm6"); + 1610 144425696 : asm volatile ("pand %xmm7,%xmm4"); + 1611 144425696 : asm volatile ("pxor %xmm4,%xmm6"); 1612 : - 1613 144395232 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); + 1613 144425696 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i])); 1614 : - 1615 144395232 : asm volatile ("pxor %xmm4,%xmm5"); - 1616 144395232 : asm volatile ("pxor %xmm4,%xmm6"); - 1617 144395232 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0])); - 1618 144395232 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16])); + 1615 144425696 : asm volatile ("pxor %xmm4,%xmm5"); + 1616 144425696 : asm volatile ("pxor %xmm4,%xmm6"); + 1617 144425696 : asm volatile ("movdqa %%xmm5,%0" : "=m" (pd[0])); + 1618 144425696 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pd[16])); 1619 : - 1620 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 1621 144395232 : asm volatile ("movdqa %xmm4,%xmm5"); - 1622 144395232 : asm volatile ("psrlw $4,%xmm5"); - 1623 144395232 : asm volatile ("pand %xmm7,%xmm4"); - 1624 144395232 : asm volatile ("pand %xmm7,%xmm5"); + 1620 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 1621 144425696 : asm volatile ("movdqa %xmm4,%xmm5"); + 1622 144425696 : asm volatile ("psrlw $4,%xmm5"); + 1623 144425696 : asm volatile ("pand %xmm7,%xmm4"); + 1624 144425696 : asm volatile ("pand %xmm7,%xmm5"); 1625 : - 1626 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); - 1627 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); - 1628 144395232 : asm volatile ("pshufb %xmm4,%xmm6"); - 1629 144395232 : asm volatile ("pshufb %xmm5,%xmm7"); - 1630 144395232 : asm volatile ("pxor %xmm6,%xmm0"); - 1631 144395232 : asm volatile ("pxor %xmm7,%xmm0"); + 1626 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0])); + 1627 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0])); + 1628 144425696 : asm volatile ("pshufb %xmm4,%xmm6"); + 1629 144425696 : asm volatile ("pshufb %xmm5,%xmm7"); + 1630 144425696 : asm volatile ("pxor %xmm6,%xmm0"); + 1631 144425696 : asm volatile ("pxor %xmm7,%xmm0"); 1632 : - 1633 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); - 1634 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); - 1635 144395232 : asm volatile ("pshufb %xmm4,%xmm6"); - 1636 144395232 : asm volatile ("pshufb %xmm5,%xmm7"); - 1637 144395232 : asm volatile ("pxor %xmm6,%xmm1"); - 1638 144395232 : asm volatile ("pxor %xmm7,%xmm1"); + 1633 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0])); + 1634 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0])); + 1635 144425696 : asm volatile ("pshufb %xmm4,%xmm6"); + 1636 144425696 : asm volatile ("pshufb %xmm5,%xmm7"); + 1637 144425696 : asm volatile ("pxor %xmm6,%xmm1"); + 1638 144425696 : asm volatile ("pxor %xmm7,%xmm1"); 1639 : - 1640 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); - 1641 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); - 1642 144395232 : asm volatile ("pshufb %xmm4,%xmm6"); - 1643 144395232 : asm volatile ("pshufb %xmm5,%xmm7"); - 1644 144395232 : asm volatile ("pxor %xmm6,%xmm2"); - 1645 144395232 : asm volatile ("pxor %xmm7,%xmm2"); + 1640 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0])); + 1641 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0])); + 1642 144425696 : asm volatile ("pshufb %xmm4,%xmm6"); + 1643 144425696 : asm volatile ("pshufb %xmm5,%xmm7"); + 1644 144425696 : asm volatile ("pxor %xmm6,%xmm2"); + 1645 144425696 : asm volatile ("pxor %xmm7,%xmm2"); 1646 : - 1647 144395232 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0])); - 1648 144395232 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0])); - 1649 144395232 : asm volatile ("pshufb %xmm4,%xmm6"); - 1650 144395232 : asm volatile ("pshufb %xmm5,%xmm7"); - 1651 144395232 : asm volatile ("pxor %xmm6,%xmm3"); - 1652 144395232 : asm volatile ("pxor %xmm7,%xmm3"); + 1647 144425696 : asm volatile ("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0])); + 1648 144425696 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0])); + 1649 144425696 : asm volatile ("pshufb %xmm4,%xmm6"); + 1650 144425696 : asm volatile ("pshufb %xmm5,%xmm7"); + 1651 144425696 : asm volatile ("pxor %xmm6,%xmm3"); + 1652 144425696 : asm volatile ("pxor %xmm7,%xmm3"); 1653 : } 1654 : 1655 : /* first disk with all coefficients at 1 */ - 1656 34597584 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); - 1657 34597584 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); - 1658 34597584 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + 1656 34605200 : asm volatile ("movdqa %0,%%xmm5" : : "m" (pd[0])); + 1657 34605200 : asm volatile ("movdqa %0,%%xmm6" : : "m" (pd[16])); + 1658 34605200 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); 1659 : - 1660 34597584 : asm volatile ("pxor %xmm4,%xmm4"); - 1661 34597584 : asm volatile ("pcmpgtb %xmm6,%xmm4"); - 1662 34597584 : asm volatile ("paddb %xmm6,%xmm6"); - 1663 34597584 : asm volatile ("pand %xmm7,%xmm4"); - 1664 34597584 : asm volatile ("pxor %xmm4,%xmm6"); + 1660 34605200 : asm volatile ("pxor %xmm4,%xmm4"); + 1661 34605200 : asm volatile ("pcmpgtb %xmm6,%xmm4"); + 1662 34605200 : asm volatile ("paddb %xmm6,%xmm6"); + 1663 34605200 : asm volatile ("pand %xmm7,%xmm4"); + 1664 34605200 : asm volatile ("pxor %xmm4,%xmm6"); 1665 : - 1666 34597584 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); - 1667 34597584 : asm volatile ("pxor %xmm4,%xmm0"); - 1668 34597584 : asm volatile ("pxor %xmm4,%xmm1"); - 1669 34597584 : asm volatile ("pxor %xmm4,%xmm2"); - 1670 34597584 : asm volatile ("pxor %xmm4,%xmm3"); - 1671 34597584 : asm volatile ("pxor %xmm4,%xmm5"); - 1672 34597584 : asm volatile ("pxor %xmm4,%xmm6"); + 1666 34605200 : asm volatile ("movdqa %0,%%xmm4" : : "m" (v[0][i])); + 1667 34605200 : asm volatile ("pxor %xmm4,%xmm0"); + 1668 34605200 : asm volatile ("pxor %xmm4,%xmm1"); + 1669 34605200 : asm volatile ("pxor %xmm4,%xmm2"); + 1670 34605200 : asm volatile ("pxor %xmm4,%xmm3"); + 1671 34605200 : asm volatile ("pxor %xmm4,%xmm5"); + 1672 34605200 : asm volatile ("pxor %xmm4,%xmm6"); 1673 : - 1674 34597584 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i])); - 1675 34597584 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i])); - 1676 34597584 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i])); - 1677 34597584 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i])); - 1678 34597584 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i])); - 1679 34597584 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i])); + 1674 34605200 : asm volatile ("movntdq %%xmm5,%0" : "=m" (p[i])); + 1675 34605200 : asm volatile ("movntdq %%xmm6,%0" : "=m" (q[i])); + 1676 34605200 : asm volatile ("movntdq %%xmm0,%0" : "=m" (r[i])); + 1677 34605200 : asm volatile ("movntdq %%xmm1,%0" : "=m" (s[i])); + 1678 34605200 : asm volatile ("movntdq %%xmm2,%0" : "=m" (t[i])); + 1679 34605200 : asm volatile ("movntdq %%xmm3,%0" : "=m" (u[i])); 1680 : } 1681 : 1682 : raid_sse_end(); @@ -2046,9 +2046,9 @@ 1984 : /* 1985 : * RAID recovering for one disk SSSE3 implementation 1986 : */ - 1987 114194 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) + 1987 114430 : void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) 1988 : { - 1989 114194 : uint8_t **v = (uint8_t **)vv; + 1989 114430 : uint8_t **v = (uint8_t **)vv; 1990 : uint8_t *p; 1991 : uint8_t *pa; 1992 : uint8_t G; @@ -2058,43 +2058,43 @@ 1996 : (void)nr; /* unused, it's always 1 */ 1997 : 1998 : /* if it's RAID5 uses the faster function */ - 1999 114194 : if (ip[0] == 0) { - 2000 104659 : raid_rec1of1(id, nd, size, vv); - 2001 218853 : return; + 1999 114430 : if (ip[0] == 0) { + 2000 104899 : raid_rec1of1(id, nd, size, vv); + 2001 219329 : return; 2002 : } 2003 : 2004 : /* setup the coefficients matrix */ - 2005 19070 : G = A(ip[0], id[0]); + 2005 19062 : G = A(ip[0], id[0]); 2006 : 2007 : /* invert it to solve the system of linear equations */ - 2008 19070 : V = inv(G); + 2008 19062 : V = inv(G); 2009 : 2010 : /* compute delta parity */ - 2011 9535 : raid_delta_gen(1, id, ip, nd, size, vv); + 2011 9531 : raid_delta_gen(1, id, ip, nd, size, vv); 2012 : - 2013 9535 : p = v[nd + ip[0]]; - 2014 9535 : pa = v[id[0]]; + 2013 9531 : p = v[nd + ip[0]]; + 2014 9531 : pa = v[id[0]]; 2015 : 2016 : raid_sse_begin(); 2017 : - 2018 9535 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); - 2019 9535 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0])); - 2020 9535 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0])); + 2018 9531 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 2019 9531 : asm volatile ("movdqa %0,%%xmm4" : : "m" (gfmulpshufb[V][0][0])); + 2020 9531 : asm volatile ("movdqa %0,%%xmm5" : : "m" (gfmulpshufb[V][1][0])); 2021 : - 2022 1529663 : for (i = 0; i < size; i += 16) { - 2023 1520128 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i])); - 2024 1520128 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i])); - 2025 1520128 : asm volatile ("movdqa %xmm4,%xmm2"); - 2026 1520128 : asm volatile ("movdqa %xmm5,%xmm3"); - 2027 1520128 : asm volatile ("pxor %xmm0,%xmm1"); - 2028 1520128 : asm volatile ("movdqa %xmm1,%xmm0"); - 2029 1520128 : asm volatile ("psrlw $4,%xmm1"); - 2030 1520128 : asm volatile ("pand %xmm7,%xmm0"); - 2031 1520128 : asm volatile ("pand %xmm7,%xmm1"); - 2032 1520128 : asm volatile ("pshufb %xmm0,%xmm2"); - 2033 1520128 : asm volatile ("pshufb %xmm1,%xmm3"); - 2034 1520128 : asm volatile ("pxor %xmm3,%xmm2"); - 2035 1520128 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i])); + 2022 1529403 : for (i = 0; i < size; i += 16) { + 2023 1519872 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[i])); + 2024 1519872 : asm volatile ("movdqa %0,%%xmm1" : : "m" (pa[i])); + 2025 1519872 : asm volatile ("movdqa %xmm4,%xmm2"); + 2026 1519872 : asm volatile ("movdqa %xmm5,%xmm3"); + 2027 1519872 : asm volatile ("pxor %xmm0,%xmm1"); + 2028 1519872 : asm volatile ("movdqa %xmm1,%xmm0"); + 2029 1519872 : asm volatile ("psrlw $4,%xmm1"); + 2030 1519872 : asm volatile ("pand %xmm7,%xmm0"); + 2031 1519872 : asm volatile ("pand %xmm7,%xmm1"); + 2032 1519872 : asm volatile ("pshufb %xmm0,%xmm2"); + 2033 1519872 : asm volatile ("pshufb %xmm1,%xmm3"); + 2034 1519872 : asm volatile ("pxor %xmm3,%xmm2"); + 2035 1519872 : asm volatile ("movdqa %%xmm2,%0" : "=m" (pa[i])); 2036 : } 2037 : 2038 : raid_sse_end(); @@ -2105,106 +2105,106 @@ 2043 : /* 2044 : * RAID recovering for two disks SSSE3 implementation 2045 : */ - 2046 44409 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) + 2046 44206 : void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv) 2047 : { - 2048 44409 : uint8_t **v = (uint8_t **)vv; - 2049 44409 : const int N = 2; - 2050 44409 : uint8_t *p[N]; - 2051 44409 : uint8_t *pa[N]; - 2052 44409 : uint8_t G[N * N]; - 2053 44409 : uint8_t V[N * N]; + 2048 44206 : uint8_t **v = (uint8_t **)vv; + 2049 44206 : const int N = 2; + 2050 44206 : uint8_t *p[N]; + 2051 44206 : uint8_t *pa[N]; + 2052 44206 : uint8_t G[N * N]; + 2053 44206 : uint8_t V[N * N]; 2054 : size_t i; 2055 : int j, k; 2056 : 2057 : (void)nr; /* unused, it's always 2 */ 2058 : 2059 : /* setup the coefficients matrix */ - 2060 133227 : for (j = 0; j < N; ++j) - 2061 266454 : for (k = 0; k < N; ++k) - 2062 355272 : G[j * N + k] = A(ip[j], id[k]); + 2060 132618 : for (j = 0; j < N; ++j) + 2061 265236 : for (k = 0; k < N; ++k) + 2062 353648 : G[j * N + k] = A(ip[j], id[k]); 2063 : 2064 : /* invert it to solve the system of linear equations */ - 2065 44409 : raid_invert(G, V, N); + 2065 44206 : raid_invert(G, V, N); 2066 : 2067 : /* compute delta parity */ - 2068 44409 : raid_delta_gen(N, id, ip, nd, size, vv); + 2068 44206 : raid_delta_gen(N, id, ip, nd, size, vv); 2069 : - 2070 133227 : for (j = 0; j < N; ++j) { - 2071 88818 : p[j] = v[nd + ip[j]]; - 2072 88818 : pa[j] = v[id[j]]; + 2070 132618 : for (j = 0; j < N; ++j) { + 2071 88412 : p[j] = v[nd + ip[j]]; + 2072 88412 : pa[j] = v[id[j]]; 2073 : } 2074 : 2075 : raid_sse_begin(); 2076 : - 2077 44409 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); + 2077 44206 : asm volatile ("movdqa %0,%%xmm7" : : "m" (gfconst16.low4[0])); 2078 : - 2079 3612921 : for (i = 0; i < size; i += 16) { - 2080 3568512 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i])); - 2081 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i])); - 2082 3568512 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i])); - 2083 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i])); - 2084 3568512 : asm volatile ("pxor %xmm2,%xmm0"); - 2085 3568512 : asm volatile ("pxor %xmm3,%xmm1"); + 2079 3599726 : for (i = 0; i < size; i += 16) { + 2080 3555520 : asm volatile ("movdqa %0,%%xmm0" : : "m" (p[0][i])); + 2081 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (pa[0][i])); + 2082 3555520 : asm volatile ("movdqa %0,%%xmm1" : : "m" (p[1][i])); + 2083 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (pa[1][i])); + 2084 3555520 : asm volatile ("pxor %xmm2,%xmm0"); + 2085 3555520 : asm volatile ("pxor %xmm3,%xmm1"); 2086 : - 2087 3568512 : asm volatile ("pxor %xmm6,%xmm6"); + 2087 3555520 : asm volatile ("pxor %xmm6,%xmm6"); 2088 : - 2089 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0])); - 2090 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0])); - 2091 3568512 : asm volatile ("movdqa %xmm0,%xmm4"); - 2092 3568512 : asm volatile ("movdqa %xmm0,%xmm5"); - 2093 3568512 : asm volatile ("psrlw $4,%xmm5"); - 2094 3568512 : asm volatile ("pand %xmm7,%xmm4"); - 2095 3568512 : asm volatile ("pand %xmm7,%xmm5"); - 2096 3568512 : asm volatile ("pshufb %xmm4,%xmm2"); - 2097 3568512 : asm volatile ("pshufb %xmm5,%xmm3"); - 2098 3568512 : asm volatile ("pxor %xmm2,%xmm6"); - 2099 3568512 : asm volatile ("pxor %xmm3,%xmm6"); + 2089 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[0]][0][0])); + 2090 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[0]][1][0])); + 2091 3555520 : asm volatile ("movdqa %xmm0,%xmm4"); + 2092 3555520 : asm volatile ("movdqa %xmm0,%xmm5"); + 2093 3555520 : asm volatile ("psrlw $4,%xmm5"); + 2094 3555520 : asm volatile ("pand %xmm7,%xmm4"); + 2095 3555520 : asm volatile ("pand %xmm7,%xmm5"); + 2096 3555520 : asm volatile ("pshufb %xmm4,%xmm2"); + 2097 3555520 : asm volatile ("pshufb %xmm5,%xmm3"); + 2098 3555520 : asm volatile ("pxor %xmm2,%xmm6"); + 2099 3555520 : asm volatile ("pxor %xmm3,%xmm6"); 2100 : - 2101 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0])); - 2102 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0])); - 2103 3568512 : asm volatile ("movdqa %xmm1,%xmm4"); - 2104 3568512 : asm volatile ("movdqa %xmm1,%xmm5"); - 2105 3568512 : asm volatile ("psrlw $4,%xmm5"); - 2106 3568512 : asm volatile ("pand %xmm7,%xmm4"); - 2107 3568512 : asm volatile ("pand %xmm7,%xmm5"); - 2108 3568512 : asm volatile ("pshufb %xmm4,%xmm2"); - 2109 3568512 : asm volatile ("pshufb %xmm5,%xmm3"); - 2110 3568512 : asm volatile ("pxor %xmm2,%xmm6"); - 2111 3568512 : asm volatile ("pxor %xmm3,%xmm6"); + 2101 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[1]][0][0])); + 2102 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[1]][1][0])); + 2103 3555520 : asm volatile ("movdqa %xmm1,%xmm4"); + 2104 3555520 : asm volatile ("movdqa %xmm1,%xmm5"); + 2105 3555520 : asm volatile ("psrlw $4,%xmm5"); + 2106 3555520 : asm volatile ("pand %xmm7,%xmm4"); + 2107 3555520 : asm volatile ("pand %xmm7,%xmm5"); + 2108 3555520 : asm volatile ("pshufb %xmm4,%xmm2"); + 2109 3555520 : asm volatile ("pshufb %xmm5,%xmm3"); + 2110 3555520 : asm volatile ("pxor %xmm2,%xmm6"); + 2111 3555520 : asm volatile ("pxor %xmm3,%xmm6"); 2112 : - 2113 3568512 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i])); + 2113 3555520 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[0][i])); 2114 : - 2115 3568512 : asm volatile ("pxor %xmm6,%xmm6"); + 2115 3555520 : asm volatile ("pxor %xmm6,%xmm6"); 2116 : - 2117 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0])); - 2118 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0])); - 2119 3568512 : asm volatile ("movdqa %xmm0,%xmm4"); - 2120 3568512 : asm volatile ("movdqa %xmm0,%xmm5"); - 2121 3568512 : asm volatile ("psrlw $4,%xmm5"); - 2122 3568512 : asm volatile ("pand %xmm7,%xmm4"); - 2123 3568512 : asm volatile ("pand %xmm7,%xmm5"); - 2124 3568512 : asm volatile ("pshufb %xmm4,%xmm2"); - 2125 3568512 : asm volatile ("pshufb %xmm5,%xmm3"); - 2126 3568512 : asm volatile ("pxor %xmm2,%xmm6"); - 2127 3568512 : asm volatile ("pxor %xmm3,%xmm6"); + 2117 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[2]][0][0])); + 2118 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[2]][1][0])); + 2119 3555520 : asm volatile ("movdqa %xmm0,%xmm4"); + 2120 3555520 : asm volatile ("movdqa %xmm0,%xmm5"); + 2121 3555520 : asm volatile ("psrlw $4,%xmm5"); + 2122 3555520 : asm volatile ("pand %xmm7,%xmm4"); + 2123 3555520 : asm volatile ("pand %xmm7,%xmm5"); + 2124 3555520 : asm volatile ("pshufb %xmm4,%xmm2"); + 2125 3555520 : asm volatile ("pshufb %xmm5,%xmm3"); + 2126 3555520 : asm volatile ("pxor %xmm2,%xmm6"); + 2127 3555520 : asm volatile ("pxor %xmm3,%xmm6"); 2128 : - 2129 3568512 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0])); - 2130 3568512 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0])); - 2131 3568512 : asm volatile ("movdqa %xmm1,%xmm4"); - 2132 3568512 : asm volatile ("movdqa %xmm1,%xmm5"); - 2133 3568512 : asm volatile ("psrlw $4,%xmm5"); - 2134 3568512 : asm volatile ("pand %xmm7,%xmm4"); - 2135 3568512 : asm volatile ("pand %xmm7,%xmm5"); - 2136 3568512 : asm volatile ("pshufb %xmm4,%xmm2"); - 2137 3568512 : asm volatile ("pshufb %xmm5,%xmm3"); - 2138 3568512 : asm volatile ("pxor %xmm2,%xmm6"); - 2139 3568512 : asm volatile ("pxor %xmm3,%xmm6"); + 2129 3555520 : asm volatile ("movdqa %0,%%xmm2" : : "m" (gfmulpshufb[V[3]][0][0])); + 2130 3555520 : asm volatile ("movdqa %0,%%xmm3" : : "m" (gfmulpshufb[V[3]][1][0])); + 2131 3555520 : asm volatile ("movdqa %xmm1,%xmm4"); + 2132 3555520 : asm volatile ("movdqa %xmm1,%xmm5"); + 2133 3555520 : asm volatile ("psrlw $4,%xmm5"); + 2134 3555520 : asm volatile ("pand %xmm7,%xmm4"); + 2135 3555520 : asm volatile ("pand %xmm7,%xmm5"); + 2136 3555520 : asm volatile ("pshufb %xmm4,%xmm2"); + 2137 3555520 : asm volatile ("pshufb %xmm5,%xmm3"); + 2138 3555520 : asm volatile ("pxor %xmm2,%xmm6"); + 2139 3555520 : asm volatile ("pxor %xmm3,%xmm6"); 2140 : - 2141 3568512 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i])); + 2141 3555520 : asm volatile ("movdqa %%xmm6,%0" : "=m" (pa[1][i])); 2142 : } 2143 : 2144 : raid_sse_end(); - 2145 44409 : } + 2145 44206 : } 2146 : #endif 2147 : 2148 : #if defined(CONFIG_X86) && defined(CONFIG_SSSE3) diff --git a/cov/raid/x86z.c.func-sort-c.html b/cov/raid/x86z.c.func-sort-c.html index ac5c96aa..cb2cfb47 100644 --- a/cov/raid/x86z.c.func-sort-c.html +++ b/cov/raid/x86z.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/raid/x86z.c.func.html b/cov/raid/x86z.c.func.html index 41e2c249..f498b4e6 100644 --- a/cov/raid/x86z.c.func.html +++ b/cov/raid/x86z.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/raid/x86z.c.gcov.html b/cov/raid/x86z.c.gcov.html index 658f2eda..9039ba20 100644 --- a/cov/raid/x86z.c.gcov.html +++ b/cov/raid/x86z.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/tommyds/index-sort-f.html b/cov/tommyds/index-sort-f.html index 0c2c28a7..10ac305b 100644 --- a/cov/tommyds/index-sort-f.html +++ b/cov/tommyds/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 82 diff --git a/cov/tommyds/index-sort-l.html b/cov/tommyds/index-sort-l.html index 42d4d7d5..ac04e945 100644 --- a/cov/tommyds/index-sort-l.html +++ b/cov/tommyds/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 82 diff --git a/cov/tommyds/index.html b/cov/tommyds/index.html index 757ddbd8..ecd00113 100644 --- a/cov/tommyds/index.html +++ b/cov/tommyds/index.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 82 diff --git a/cov/tommyds/tommyarray.c.func-sort-c.html b/cov/tommyds/tommyarray.c.func-sort-c.html index b7c42076..eb0f50ec 100644 --- a/cov/tommyds/tommyarray.c.func-sort-c.html +++ b/cov/tommyds/tommyarray.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarray.c.func.html b/cov/tommyds/tommyarray.c.func.html index 9ea01c20..ea4d5acb 100644 --- a/cov/tommyds/tommyarray.c.func.html +++ b/cov/tommyds/tommyarray.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarray.c.gcov.html b/cov/tommyds/tommyarray.c.gcov.html index f9f40a61..1e28d9b1 100644 --- a/cov/tommyds/tommyarray.c.gcov.html +++ b/cov/tommyds/tommyarray.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarray.h.func-sort-c.html b/cov/tommyds/tommyarray.h.func-sort-c.html index f5bb5e63..47f38cb2 100644 --- a/cov/tommyds/tommyarray.h.func-sort-c.html +++ b/cov/tommyds/tommyarray.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -60,12 +60,12 @@ Hit count Sort by hit count - tommy_array_ref - 15269081 + tommy_array_get + 15295882 - tommy_array_get - 15267826 + tommy_array_ref + 15273609 tommy_array_size diff --git a/cov/tommyds/tommyarray.h.func.html b/cov/tommyds/tommyarray.h.func.html index 0c171236..094f71fc 100644 --- a/cov/tommyds/tommyarray.h.func.html +++ b/cov/tommyds/tommyarray.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -61,7 +61,7 @@ tommy_array_get - 15267826 + 15295882 tommy_array_insert @@ -69,7 +69,7 @@ tommy_array_ref - 15269081 + 15273609 tommy_array_set diff --git a/cov/tommyds/tommyarray.h.gcov.html b/cov/tommyds/tommyarray.h.gcov.html index 4f787277..306db8c1 100644 --- a/cov/tommyds/tommyarray.h.gcov.html +++ b/cov/tommyds/tommyarray.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -152,16 +152,16 @@ 90 : * You must be sure that space for this position is already 91 : * allocated calling tommy_array_grow(). 92 : */ - 93 15269081 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) + 93 15273609 : tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) 94 : { 95 : tommy_uint_t bsr; 96 : - 97 15269081 : assert(pos < array->count); + 97 15273609 : assert(pos < array->count); 98 : 99 : /* get the highest bit set, in case of all 0, return 0 */ - 100 15269081 : bsr = tommy_ilog2_u32(pos | 1); + 100 15273609 : bsr = tommy_ilog2_u32(pos | 1); 101 : - 102 15272644 : return &array->bucket[bsr][pos]; + 102 15288941 : return &array->bucket[bsr][pos]; 103 : } 104 : 105 : /** @@ -179,9 +179,9 @@ 117 : * You must be sure that space for this position is already 118 : * allocated calling tommy_array_grow(). 119 : */ - 120 15267826 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) + 120 15295882 : tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) 121 : { - 122 15267826 : return *tommy_array_ref(array, pos); + 122 15295882 : return *tommy_array_ref(array, pos); 123 : } 124 : 125 : /** diff --git a/cov/tommyds/tommyarrayblk.c.func-sort-c.html b/cov/tommyds/tommyarrayblk.c.func-sort-c.html index 323d33c2..b81595fd 100644 --- a/cov/tommyds/tommyarrayblk.c.func-sort-c.html +++ b/cov/tommyds/tommyarrayblk.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarrayblk.c.func.html b/cov/tommyds/tommyarrayblk.c.func.html index e52e0c62..06bbfd2d 100644 --- a/cov/tommyds/tommyarrayblk.c.func.html +++ b/cov/tommyds/tommyarrayblk.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarrayblk.c.gcov.html b/cov/tommyds/tommyarrayblk.c.gcov.html index 1b7676f4..deef2d86 100644 --- a/cov/tommyds/tommyarrayblk.c.gcov.html +++ b/cov/tommyds/tommyarrayblk.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarrayblk.h.func-sort-c.html b/cov/tommyds/tommyarrayblk.h.func-sort-c.html index 5ca27edb..774c7f4c 100644 --- a/cov/tommyds/tommyarrayblk.h.func-sort-c.html +++ b/cov/tommyds/tommyarrayblk.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarrayblk.h.func.html b/cov/tommyds/tommyarrayblk.h.func.html index 7516b3fa..0c988a32 100644 --- a/cov/tommyds/tommyarrayblk.h.func.html +++ b/cov/tommyds/tommyarrayblk.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarrayblk.h.gcov.html b/cov/tommyds/tommyarrayblk.h.gcov.html index edab3915..dd4893ab 100644 --- a/cov/tommyds/tommyarrayblk.h.gcov.html +++ b/cov/tommyds/tommyarrayblk.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 diff --git a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html index 805ac844..9b15c5a4 100644 --- a/cov/tommyds/tommyarrayblkof.c.func-sort-c.html +++ b/cov/tommyds/tommyarrayblkof.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -61,7 +61,7 @@ tommy_arrayblkof_grow - 1609618 + 1609741 tommy_arrayblkof_init diff --git a/cov/tommyds/tommyarrayblkof.c.func.html b/cov/tommyds/tommyarrayblkof.c.func.html index 36a316ad..17140f12 100644 --- a/cov/tommyds/tommyarrayblkof.c.func.html +++ b/cov/tommyds/tommyarrayblkof.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -65,7 +65,7 @@ tommy_arrayblkof_grow - 1609618 + 1609741 tommy_arrayblkof_init diff --git a/cov/tommyds/tommyarrayblkof.c.gcov.html b/cov/tommyds/tommyarrayblkof.c.gcov.html index ccce00da..4da680ca 100644 --- a/cov/tommyds/tommyarrayblkof.c.gcov.html +++ b/cov/tommyds/tommyarrayblkof.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 4 @@ -110,13 +110,13 @@ 48 227 : tommy_array_done(&array->block); 49 227 : } 50 : - 51 1609618 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count) + 51 1609741 : void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count) 52 : { 53 : tommy_count_t block_max; 54 : tommy_count_t block_mac; 55 : - 56 1609618 : if (array->count >= count) - 57 1700455 : return; + 56 1609741 : if (array->count >= count) + 57 1700701 : return; 58 1518781 : array->count = count; 59 : 60 1518781 : block_max = (count + TOMMY_ARRAYBLKOF_SIZE - 1) / TOMMY_ARRAYBLKOF_SIZE; diff --git a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html index 7c3ce483..5a904630 100644 --- a/cov/tommyds/tommyarrayblkof.h.func-sort-c.html +++ b/cov/tommyds/tommyarrayblkof.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,11 +61,11 @@ tommy_arrayblkof_ref - 11669209 + 11688426 tommy_arrayblkof_size - 10549174 + 10571361
diff --git a/cov/tommyds/tommyarrayblkof.h.func.html b/cov/tommyds/tommyarrayblkof.h.func.html index 296efe6a..aab7c7c9 100644 --- a/cov/tommyds/tommyarrayblkof.h.func.html +++ b/cov/tommyds/tommyarrayblkof.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,11 +61,11 @@ tommy_arrayblkof_ref - 11669209 + 11688426 tommy_arrayblkof_size - 10549174 + 10571361
diff --git a/cov/tommyds/tommyarrayblkof.h.gcov.html b/cov/tommyds/tommyarrayblkof.h.gcov.html index d35382c5..41d4c08a 100644 --- a/cov/tommyds/tommyarrayblkof.h.gcov.html +++ b/cov/tommyds/tommyarrayblkof.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -148,23 +148,23 @@ 86 : * You must be sure that space for this position is already 87 : * allocated calling tommy_arrayblkof_grow(). 88 : */ - 89 11669209 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos) + 89 11688426 : tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos) 90 : { 91 : unsigned char* base; 92 : - 93 11669209 : assert(pos < array->count); + 93 11688426 : assert(pos < array->count); 94 : - 95 11669209 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE)); + 95 11688426 : base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE)); 96 : - 97 11653374 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size; + 97 11693987 : return base + (pos % TOMMY_ARRAYBLKOF_SIZE) * array->element_size; 98 : } 99 : 100 : /** 101 : * Gets the initialized size of the array. 102 : */ - 103 10549174 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array) + 103 10571361 : tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array) 104 : { - 105 10549174 : return array->count; + 105 10571361 : return array->count; 106 : } 107 : 108 : /** diff --git a/cov/tommyds/tommychain.h.func-sort-c.html b/cov/tommyds/tommychain.h.func-sort-c.html index dec46b5c..9f911f5f 100644 --- a/cov/tommyds/tommychain.h.func-sort-c.html +++ b/cov/tommyds/tommychain.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -61,19 +61,19 @@ tommy_chain_splice - 4083447 + 4073661 tommy_chain_merge_degenerated - 1153837 + 1153954 tommy_chain_concat - 1147561 + 1147870 tommy_chain_merge - 427404 + 427121 tommy_chain_mergesort diff --git a/cov/tommyds/tommychain.h.func.html b/cov/tommyds/tommychain.h.func.html index 52908717..5ac1a9e6 100644 --- a/cov/tommyds/tommychain.h.func.html +++ b/cov/tommyds/tommychain.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -61,15 +61,15 @@ tommy_chain_concat - 1147561 + 1147870 tommy_chain_merge - 427404 + 427121 tommy_chain_merge_degenerated - 1153837 + 1153954 tommy_chain_mergesort @@ -77,7 +77,7 @@ tommy_chain_splice - 4083447 + 4073661
diff --git a/cov/tommyds/tommychain.h.gcov.html b/cov/tommyds/tommychain.h.gcov.html index 604fb394..8ed60019 100644 --- a/cov/tommyds/tommychain.h.gcov.html +++ b/cov/tommyds/tommychain.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 5 @@ -119,83 +119,83 @@ 57 : /** 58 : * Splices a chain in the middle of another chain. 59 : */ - 60 4083447 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail) + 60 4073661 : tommy_inline void tommy_chain_splice(tommy_node* first_before, tommy_node* first_after, tommy_node* second_head, tommy_node* second_tail) 61 : { 62 : /* set the prev list */ - 63 4083447 : first_after->prev = second_tail; - 64 4083447 : second_head->prev = first_before; + 63 4073661 : first_after->prev = second_tail; + 64 4073661 : second_head->prev = first_before; 65 : 66 : /* set the next list */ - 67 4083447 : first_before->next = second_head; - 68 4083447 : second_tail->next = first_after; - 69 4083447 : } + 67 4073661 : first_before->next = second_head; + 68 4073661 : second_tail->next = first_after; + 69 4073661 : } 70 : 71 : /** 72 : * Concats two chains. 73 : */ - 74 1147561 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head) + 74 1147870 : tommy_inline void tommy_chain_concat(tommy_node* first_tail, tommy_node* second_head) 75 : { 76 : /* set the prev list */ - 77 1147561 : second_head->prev = first_tail; + 77 1147870 : second_head->prev = first_tail; 78 : 79 : /* set the next list */ - 80 1147561 : first_tail->next = second_head; - 81 1147561 : } + 80 1147870 : first_tail->next = second_head; + 81 1147870 : } 82 : 83 : /** 84 : * Merges two chains. 85 : */ - 86 427404 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) + 86 427121 : tommy_inline void tommy_chain_merge(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) 87 : { - 88 427404 : tommy_node* first_i = first->head; - 89 427404 : tommy_node* second_i = second->head; + 88 427121 : tommy_node* first_i = first->head; + 89 427121 : tommy_node* second_i = second->head; 90 : 91 : /* merge */ 92 : while (1) { - 93 8885557 : if (cmp(first_i->data, second_i->data) > 0) { - 94 4294267 : tommy_node* next = second_i->next; - 95 4294267 : if (first_i == first->head) { - 96 210820 : tommy_chain_concat(second_i, first_i); - 97 210820 : first->head = second_i; + 93 8866117 : if (cmp(first_i->data, second_i->data) > 0) { + 94 4284467 : tommy_node* next = second_i->next; + 95 4284467 : if (first_i == first->head) { + 96 210806 : tommy_chain_concat(second_i, first_i); + 97 210806 : first->head = second_i; 98 : } else { - 99 4083447 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i); + 99 4073661 : tommy_chain_splice(first_i->prev, first_i, second_i, second_i); 100 : } - 101 4294267 : if (second_i == second->tail) - 102 217096 : break; - 103 4077171 : second_i = next; + 101 4284467 : if (second_i == second->tail) + 102 216890 : break; + 103 4067577 : second_i = next; 104 : } else { - 105 4591290 : if (first_i == first->tail) { - 106 210308 : tommy_chain_concat(first_i, second_i); - 107 210308 : first->tail = second->tail; - 108 210308 : break; + 105 4581650 : if (first_i == first->tail) { + 106 210231 : tommy_chain_concat(first_i, second_i); + 107 210231 : first->tail = second->tail; + 108 210231 : break; 109 : } - 110 4380982 : first_i = first_i->next; + 110 4371419 : first_i = first_i->next; 111 : } - 112 8458153 : } - 113 427404 : } + 112 8438996 : } + 113 427121 : } 114 : 115 : /** 116 : * Merges two chains managing special degenerated cases. 117 : * It's funtionally equivalent at tommy_chain_merge() but faster with already ordered chains. 118 : */ - 119 1153837 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) + 119 1153954 : tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* second, tommy_compare_func* cmp) 120 : { 121 : /* identify the condition first <= second */ - 122 1153837 : if (cmp(first->tail->data, second->head->data) <= 0) { - 123 422569 : tommy_chain_concat(first->tail, second->head); - 124 422569 : first->tail = second->tail; - 125 422569 : return; + 122 1153954 : if (cmp(first->tail->data, second->head->data) <= 0) { + 123 422991 : tommy_chain_concat(first->tail, second->head); + 124 422991 : first->tail = second->tail; + 125 422991 : return; 126 : } 127 : 128 : /* identify the condition second < first */ 129 : /* here we must be strict on comparison to keep the sort stable */ - 130 731268 : if (cmp(second->tail->data, first->head->data) < 0) { - 131 303864 : tommy_chain_concat(second->tail, first->head); - 132 303864 : first->head = second->head; - 133 303864 : return; + 130 730963 : if (cmp(second->tail->data, first->head->data) < 0) { + 131 303842 : tommy_chain_concat(second->tail, first->head); + 132 303842 : first->head = second->head; + 133 303842 : return; 134 : } 135 : - 136 427404 : tommy_chain_merge(first, second, cmp); + 136 427121 : tommy_chain_merge(first, second, cmp); 137 : } 138 : 139 : /** @@ -241,42 +241,42 @@ 179 : tommy_chain* last; 180 : 181 : /* carry bit to add */ - 182 1155310 : last = &bit[TOMMY_CHAIN_BIT_MAX]; - 183 1155310 : bit[TOMMY_CHAIN_BIT_MAX].head = node; - 184 1155310 : bit[TOMMY_CHAIN_BIT_MAX].tail = node; - 185 1155310 : next = node->next; + 182 1155427 : last = &bit[TOMMY_CHAIN_BIT_MAX]; + 183 1155427 : bit[TOMMY_CHAIN_BIT_MAX].head = node; + 184 1155427 : bit[TOMMY_CHAIN_BIT_MAX].tail = node; + 185 1155427 : next = node->next; 186 : 187 : /* add the bit, propagating the carry */ - 188 1155310 : i = 0; - 189 1155310 : mask = counter; - 190 3459162 : while ((mask & 1) != 0) { - 191 1148542 : tommy_chain_merge_degenerated(&bit[i], last, cmp); - 192 1148542 : mask >>= 1; - 193 1148542 : last = &bit[i]; - 194 1148542 : ++i; + 188 1155427 : i = 0; + 189 1155427 : mask = counter; + 190 3459506 : while ((mask & 1) != 0) { + 191 1148652 : tommy_chain_merge_degenerated(&bit[i], last, cmp); + 192 1148652 : mask >>= 1; + 193 1148652 : last = &bit[i]; + 194 1148652 : ++i; 195 : } 196 : 197 : /* copy the carry in the first empty bit */ - 198 1155310 : bit[i] = *last; + 198 1155427 : bit[i] = *last; 199 : 200 : /* add the carry in the counter */ - 201 1155310 : ++counter; + 201 1155427 : ++counter; 202 : - 203 1155310 : if (node == tail) + 203 1155427 : if (node == tail) 204 1473 : break; - 205 1153837 : node = next; - 206 1153837 : } + 205 1153954 : node = next; + 206 1153954 : } 207 : 208 : /* merge the buckets */ 209 1473 : i = tommy_ctz_u32(counter); 210 1473 : mask = counter >> i; - 211 10798 : while (mask != 1) { - 212 7852 : mask >>= 1; - 213 7852 : if (mask & 1) - 214 5295 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp); + 211 10792 : while (mask != 1) { + 212 7846 : mask >>= 1; + 213 7846 : if (mask & 1) + 214 5302 : tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp); 215 : else - 216 2557 : bit[i + 1] = bit[i]; - 217 7852 : ++i; + 216 2544 : bit[i + 1] = bit[i]; + 217 7846 : ++i; 218 : } 219 : 220 1473 : *chain = bit[i]; diff --git a/cov/tommyds/tommyhash.c.func-sort-c.html b/cov/tommyds/tommyhash.c.func-sort-c.html index d96977bb..9466aeab 100644 --- a/cov/tommyds/tommyhash.c.func-sort-c.html +++ b/cov/tommyds/tommyhash.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -61,11 +61,11 @@ tommy_le_uint32_read - 11236413 + 11236438 tommy_hash_u32 - 3932695 + 3932841 tommy_hash_u64 diff --git a/cov/tommyds/tommyhash.c.func.html b/cov/tommyds/tommyhash.c.func.html index 87d1f19a..311a42c9 100644 --- a/cov/tommyds/tommyhash.c.func.html +++ b/cov/tommyds/tommyhash.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -61,7 +61,7 @@ tommy_hash_u32 - 3932695 + 3932841 tommy_hash_u64 @@ -69,7 +69,7 @@ tommy_le_uint32_read - 11236413 + 11236438
diff --git a/cov/tommyds/tommyhash.c.gcov.html b/cov/tommyds/tommyhash.c.gcov.html index f2d62a19..30b59be8 100644 --- a/cov/tommyds/tommyhash.c.gcov.html +++ b/cov/tommyds/tommyhash.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -92,12 +92,12 @@ 30 : /******************************************************************************/ 31 : /* hash */ 32 : - 33 11236413 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr) + 33 11236438 : tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr) 34 : { 35 : /* allow unaligned read on Intel x86 and x86_64 platforms */ 36 : #if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__x86_64__) || defined(_M_X64) 37 : /* defines from http://predef.sourceforge.net/ */ - 38 11236413 : return *(const tommy_uint32_t*)ptr; + 38 11236438 : return *(const tommy_uint32_t*)ptr; 39 : #else 40 : const unsigned char* ptr8 = tommy_cast(const unsigned char*, ptr); 41 : return ptr8[0] + ((tommy_uint32_t)ptr8[1] << 8) + ((tommy_uint32_t)ptr8[2] << 16) + ((tommy_uint32_t)ptr8[3] << 24); @@ -128,53 +128,53 @@ 66 : c ^= b; c -= tommy_rot(b, 24); \ 67 : } while (0) 68 : - 69 3932695 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len) + 69 3932841 : tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len) 70 : { - 71 3932695 : const unsigned char* key = tommy_cast(const unsigned char*, void_key); + 71 3932841 : const unsigned char* key = tommy_cast(const unsigned char*, void_key); 72 : tommy_uint32_t a, b, c; 73 : - 74 3932695 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val; + 74 3932841 : a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val; 75 : - 76 9922363 : while (key_len > 12) { - 77 2056973 : a += tommy_le_uint32_read(key + 0); - 78 2056973 : b += tommy_le_uint32_read(key + 4); - 79 2056973 : c += tommy_le_uint32_read(key + 8); + 76 9922648 : while (key_len > 12) { + 77 2056966 : a += tommy_le_uint32_read(key + 0); + 78 2056966 : b += tommy_le_uint32_read(key + 4); + 79 2056966 : c += tommy_le_uint32_read(key + 8); 80 : - 81 2056973 : tommy_mix(a, b, c); + 81 2056966 : tommy_mix(a, b, c); 82 : - 83 2056973 : key_len -= 12; - 84 2056973 : key += 12; + 83 2056966 : key_len -= 12; + 84 2056966 : key += 12; 85 : } 86 : - 87 3932695 : switch (key_len) { + 87 3932841 : switch (key_len) { 88 : case 0 : 89 1 : return c; /* used only when called with a zero length */ 90 : case 12 : - 91 201767 : c += tommy_le_uint32_read(key + 8); - 92 201767 : b += tommy_le_uint32_read(key + 4); - 93 201767 : a += tommy_le_uint32_read(key + 0); - 94 201767 : break; - 95 210935 : case 11 : c += ((tommy_uint32_t)key[10]) << 16; - 96 620774 : case 10 : c += ((tommy_uint32_t)key[9]) << 8; - 97 1027793 : case 9 : c += key[8]; + 91 201770 : c += tommy_le_uint32_read(key + 8); + 92 201770 : b += tommy_le_uint32_read(key + 4); + 93 201770 : a += tommy_le_uint32_read(key + 0); + 94 201770 : break; + 95 210915 : case 11 : c += ((tommy_uint32_t)key[10]) << 16; + 96 620733 : case 10 : c += ((tommy_uint32_t)key[9]) << 8; + 97 1027724 : case 9 : c += key[8]; 98 : case 8 : - 99 1426056 : b += tommy_le_uint32_read(key + 4); - 100 1426056 : a += tommy_le_uint32_read(key + 0); - 101 1426056 : break; - 102 399999 : case 7 : b += ((tommy_uint32_t)key[6]) << 16; - 103 787115 : case 6 : b += ((tommy_uint32_t)key[5]) << 8; - 104 1189275 : case 5 : b += key[4]; + 99 1425951 : b += tommy_le_uint32_read(key + 4); + 100 1425951 : a += tommy_le_uint32_read(key + 0); + 101 1425951 : break; + 102 400019 : case 7 : b += ((tommy_uint32_t)key[6]) << 16; + 103 787136 : case 6 : b += ((tommy_uint32_t)key[5]) << 8; + 104 1189288 : case 5 : b += key[4]; 105 : case 4 : - 106 1608032 : a += tommy_le_uint32_read(key + 0); - 107 1608032 : break; - 108 291889 : case 3 : a += ((tommy_uint32_t)key[2]) << 16; - 109 493294 : case 2 : a += ((tommy_uint32_t)key[1]) << 8; - 110 696839 : case 1 : a += key[0]; + 106 1608279 : a += tommy_le_uint32_read(key + 0); + 107 1608279 : break; + 108 291874 : case 3 : a += ((tommy_uint32_t)key[2]) << 16; + 109 493291 : case 2 : a += ((tommy_uint32_t)key[1]) << 8; + 110 696840 : case 1 : a += key[0]; 111 : } 112 : - 113 3932694 : tommy_final(a, b, c); + 113 3932840 : tommy_final(a, b, c); 114 : - 115 3932694 : return c; + 115 3932840 : return c; 116 : } 117 : 118 19 : tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len) diff --git a/cov/tommyds/tommyhash.h.func-sort-c.html b/cov/tommyds/tommyhash.h.func-sort-c.html index 1106f6e3..bd9b8354 100644 --- a/cov/tommyds/tommyhash.h.func-sort-c.html +++ b/cov/tommyds/tommyhash.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,11 +61,11 @@ tommy_inthash_u32 - 18417585 + 18417414 tommy_inthash_u64 - 4822885 + 4822298
diff --git a/cov/tommyds/tommyhash.h.func.html b/cov/tommyds/tommyhash.h.func.html index 49cfcdb7..d1761086 100644 --- a/cov/tommyds/tommyhash.h.func.html +++ b/cov/tommyds/tommyhash.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,11 +61,11 @@ tommy_inthash_u32 - 18417585 + 18417414 tommy_inthash_u64 - 4822885 + 4822298
diff --git a/cov/tommyds/tommyhash.h.gcov.html b/cov/tommyds/tommyhash.h.gcov.html index 71771923..33130e85 100644 --- a/cov/tommyds/tommyhash.h.gcov.html +++ b/cov/tommyds/tommyhash.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -139,17 +139,17 @@ 77 : * Implementation of the Robert Jenkins "4-byte Integer Hashing", 78 : * from http://burtleburtle.net/bob/hash/integer.html 79 : */ - 80 18417585 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key) + 80 18417414 : tommy_inline tommy_uint32_t tommy_inthash_u32(tommy_uint32_t key) 81 : { - 82 18417585 : key -= key << 6; - 83 18417585 : key ^= key >> 17; - 84 18417585 : key -= key << 9; - 85 18417585 : key ^= key << 4; - 86 18417585 : key -= key << 3; - 87 18417585 : key ^= key << 10; - 88 18417585 : key ^= key >> 15; + 82 18417414 : key -= key << 6; + 83 18417414 : key ^= key >> 17; + 84 18417414 : key -= key << 9; + 85 18417414 : key ^= key << 4; + 86 18417414 : key -= key << 3; + 87 18417414 : key ^= key << 10; + 88 18417414 : key ^= key >> 15; 89 : - 90 18417585 : return key; + 90 18417414 : return key; 91 : } 92 : 93 : /** @@ -157,17 +157,17 @@ 95 : * Implementation of the Thomas Wang "Integer Hash Function", 96 : * from http://www.cris.com/~Ttwang/tech/inthash.htm 97 : */ - 98 4822885 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key) + 98 4822298 : tommy_inline tommy_uint64_t tommy_inthash_u64(tommy_uint64_t key) 99 : { - 100 4822885 : key = ~key + (key << 21); - 101 4822885 : key = key ^ (key >> 24); - 102 4822885 : key = key + (key << 3) + (key << 8); - 103 4822885 : key = key ^ (key >> 14); - 104 4822885 : key = key + (key << 2) + (key << 4); - 105 4822885 : key = key ^ (key >> 28); - 106 4822885 : key = key + (key << 31); + 100 4822298 : key = ~key + (key << 21); + 101 4822298 : key = key ^ (key >> 24); + 102 4822298 : key = key + (key << 3) + (key << 8); + 103 4822298 : key = key ^ (key >> 14); + 104 4822298 : key = key + (key << 2) + (key << 4); + 105 4822298 : key = key ^ (key >> 28); + 106 4822298 : key = key + (key << 31); 107 : - 108 4822885 : return key; + 108 4822298 : return key; 109 : } 110 : 111 : #endif diff --git a/cov/tommyds/tommyhashdyn.c.func-sort-c.html b/cov/tommyds/tommyhashdyn.c.func-sort-c.html index f543d5bf..13e53317 100644 --- a/cov/tommyds/tommyhashdyn.c.func-sort-c.html +++ b/cov/tommyds/tommyhashdyn.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 @@ -61,23 +61,23 @@ hashdyn_grow_step - 12860390 + 12860296 tommy_hashdyn_insert - 12860390 + 12860296 hashdyn_shrink_step - 284934 + 284348 tommy_hashdyn_remove_existing - 284806 + 284220 tommy_hashdyn_resize - 39872 + 39860 tommy_hashdyn_init diff --git a/cov/tommyds/tommyhashdyn.c.func.html b/cov/tommyds/tommyhashdyn.c.func.html index 4c5af758..190f8d85 100644 --- a/cov/tommyds/tommyhashdyn.c.func.html +++ b/cov/tommyds/tommyhashdyn.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 @@ -61,11 +61,11 @@ hashdyn_grow_step - 12860390 + 12860296 hashdyn_shrink_step - 284934 + 284348 tommy_hashdyn_done @@ -85,7 +85,7 @@ tommy_hashdyn_insert - 12860390 + 12860296 tommy_hashdyn_memory_usage @@ -97,11 +97,11 @@ tommy_hashdyn_remove_existing - 284806 + 284220 tommy_hashdyn_resize - 39872 + 39860
diff --git a/cov/tommyds/tommyhashdyn.c.gcov.html b/cov/tommyds/tommyhashdyn.c.gcov.html index cd764bc7..b140fbee 100644 --- a/cov/tommyds/tommyhashdyn.c.gcov.html +++ b/cov/tommyds/tommyhashdyn.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 11 @@ -112,7 +112,7 @@ 50 : /** 51 : * Resize the bucket vector. 52 : */ - 53 39872 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) + 53 39860 : static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) 54 : { 55 : tommy_count_t bucket_bit; 56 : tommy_count_t bucket_max; @@ -120,38 +120,38 @@ 58 : tommy_count_t new_bucket_mask; 59 : tommy_hashdyn_node** new_bucket; 60 : - 61 39872 : bucket_bit = hashdyn->bucket_bit; - 62 39872 : bucket_max = hashdyn->bucket_max; + 61 39860 : bucket_bit = hashdyn->bucket_bit; + 62 39860 : bucket_max = hashdyn->bucket_max; 63 : - 64 39872 : new_bucket_max = 1 << new_bucket_bit; - 65 39872 : new_bucket_mask = new_bucket_max - 1; + 64 39860 : new_bucket_max = 1 << new_bucket_bit; + 65 39860 : new_bucket_mask = new_bucket_max - 1; 66 : 67 : /* allocate the new vector using malloc() and not calloc() */ 68 : /* because data is fully initialized in the update process */ - 69 39872 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*))); + 69 39860 : new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*))); 70 : 71 : /* reinsert all the elements */ - 72 39872 : if (new_bucket_bit > bucket_bit) { + 72 39860 : if (new_bucket_bit > bucket_bit) { 73 : tommy_count_t i; 74 : 75 : /* grow */ - 76 31392079 : for (i = 0; i < bucket_max; ++i) { + 76 31390627 : for (i = 0; i < bucket_max; ++i) { 77 : tommy_hashdyn_node* j; 78 : 79 : /* setup the new two buckets */ - 80 31352256 : new_bucket[i] = 0; - 81 31352256 : new_bucket[i + bucket_max] = 0; + 80 31350816 : new_bucket[i] = 0; + 81 31350816 : new_bucket[i + bucket_max] = 0; 82 : 83 : /* reinsert the bucket */ - 84 31352256 : j = hashdyn->bucket[i]; - 85 78380640 : while (j) { - 86 15676128 : tommy_hashdyn_node* j_next = j->next; - 87 15676128 : tommy_count_t pos = j->key & new_bucket_mask; - 88 15676128 : if (new_bucket[pos]) - 89 1859714 : tommy_list_insert_tail_not_empty(new_bucket[pos], j); + 84 31350816 : j = hashdyn->bucket[i]; + 85 78377040 : while (j) { + 86 15675408 : tommy_hashdyn_node* j_next = j->next; + 87 15675408 : tommy_count_t pos = j->key & new_bucket_mask; + 88 15675408 : if (new_bucket[pos]) + 89 1860861 : tommy_list_insert_tail_not_empty(new_bucket[pos], j); 90 : else - 91 13816414 : tommy_list_insert_first(&new_bucket[pos], j); - 92 15676128 : j = j_next; + 91 13814547 : tommy_list_insert_first(&new_bucket[pos], j); + 92 15675408 : j = j_next; 93 : } 94 : } 95 : } else { @@ -167,59 +167,59 @@ 105 : } 106 : } 107 : - 108 39872 : tommy_free(hashdyn->bucket); + 108 39860 : tommy_free(hashdyn->bucket); 109 : 110 : /* setup */ - 111 39872 : hashdyn->bucket_bit = new_bucket_bit; - 112 39872 : hashdyn->bucket_max = new_bucket_max; - 113 39872 : hashdyn->bucket_mask = new_bucket_mask; - 114 39872 : hashdyn->bucket = new_bucket; - 115 39872 : } + 111 39860 : hashdyn->bucket_bit = new_bucket_bit; + 112 39860 : hashdyn->bucket_max = new_bucket_max; + 113 39860 : hashdyn->bucket_mask = new_bucket_mask; + 114 39860 : hashdyn->bucket = new_bucket; + 115 39860 : } 116 : 117 : /** 118 : * Grow. 119 : */ - 120 12860390 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn) + 120 12860296 : tommy_inline void hashdyn_grow_step(tommy_hashdyn* hashdyn) 121 : { 122 : /* grow if more than 50% full */ - 123 12860390 : if (hashdyn->count >= hashdyn->bucket_max / 2) - 124 39823 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1); - 125 12860390 : } + 123 12860296 : if (hashdyn->count >= hashdyn->bucket_max / 2) + 124 39811 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit + 1); + 125 12860296 : } 126 : 127 : /** 128 : * Shrink. 129 : */ - 130 284934 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) + 130 284348 : tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) 131 : { 132 : /* shrink if less than 12.5% full */ - 133 284934 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT) + 133 284348 : if (hashdyn->count <= hashdyn->bucket_max / 8 && hashdyn->bucket_bit > TOMMY_HASHDYN_BIT) 134 49 : tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1); - 135 284934 : } + 135 284348 : } 136 : - 137 12860390 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) + 137 12860296 : void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) 138 : { - 139 12860390 : tommy_count_t pos = hash & hashdyn->bucket_mask; + 139 12860296 : tommy_count_t pos = hash & hashdyn->bucket_mask; 140 : - 141 12860390 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); + 141 12860296 : tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); 142 : - 143 12860390 : node->key = hash; + 143 12860296 : node->key = hash; 144 : - 145 12860390 : ++hashdyn->count; + 145 12860296 : ++hashdyn->count; 146 : - 147 12860390 : hashdyn_grow_step(hashdyn); - 148 12860390 : } + 147 12860296 : hashdyn_grow_step(hashdyn); + 148 12860296 : } 149 : - 150 284806 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) + 150 284220 : void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) 151 : { - 152 284806 : tommy_count_t pos = node->key & hashdyn->bucket_mask; + 152 284220 : tommy_count_t pos = node->key & hashdyn->bucket_mask; 153 : - 154 284806 : tommy_list_remove_existing(&hashdyn->bucket[pos], node); + 154 284220 : tommy_list_remove_existing(&hashdyn->bucket[pos], node); 155 : - 156 284806 : --hashdyn->count; + 156 284220 : --hashdyn->count; 157 : - 158 284806 : hashdyn_shrink_step(hashdyn); + 158 284220 : hashdyn_shrink_step(hashdyn); 159 : - 160 284806 : return node->data; + 160 284220 : return node->data; 161 : } 162 : 163 256 : void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) @@ -253,10 +253,10 @@ 191 5812246 : for (pos = 0; pos < bucket_max; ++pos) { 192 5812016 : tommy_hashdyn_node* node = bucket[pos]; 193 : - 194 13483575 : while (node) { - 195 1859543 : void* data = node->data; - 196 1859543 : node = node->next; - 197 1859543 : func(data); + 194 13483818 : while (node) { + 195 1859786 : void* data = node->data; + 196 1859786 : node = node->next; + 197 1859786 : func(data); 198 : } 199 : } 200 230 : } diff --git a/cov/tommyds/tommyhashdyn.h.func-sort-c.html b/cov/tommyds/tommyhashdyn.h.func-sort-c.html index bffd008b..524259cb 100644 --- a/cov/tommyds/tommyhashdyn.h.func-sort-c.html +++ b/cov/tommyds/tommyhashdyn.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -61,11 +61,11 @@ tommy_hashdyn_bucket - 3071206 + 3070554 tommy_hashdyn_search - 3071206 + 3070554 tommy_hashdyn_count diff --git a/cov/tommyds/tommyhashdyn.h.func.html b/cov/tommyds/tommyhashdyn.h.func.html index 61832970..204c62c7 100644 --- a/cov/tommyds/tommyhashdyn.h.func.html +++ b/cov/tommyds/tommyhashdyn.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -61,7 +61,7 @@ tommy_hashdyn_bucket - 3071206 + 3070554 tommy_hashdyn_count @@ -69,7 +69,7 @@ tommy_hashdyn_search - 3071206 + 3070554
diff --git a/cov/tommyds/tommyhashdyn.h.gcov.html b/cov/tommyds/tommyhashdyn.h.gcov.html index dae096d7..448c8108 100644 --- a/cov/tommyds/tommyhashdyn.h.gcov.html +++ b/cov/tommyds/tommyhashdyn.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -267,9 +267,9 @@ 205 : * \param hash Hash of the element to find. 206 : * \return The head of the bucket, or 0 if empty. 207 : */ - 208 3071206 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash) + 208 3070554 : tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash) 209 : { - 210 3071206 : return hashdyn->bucket[hash & hashdyn->bucket_mask]; + 210 3070554 : return hashdyn->bucket[hash & hashdyn->bucket_mask]; 211 : } 212 : 213 : /** @@ -282,17 +282,17 @@ 220 : * \param hash Hash of the element to find. 221 : * \return The first element found, or 0 if none. 222 : */ - 223 3071206 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) + 223 3070554 : tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) 224 : { - 225 3071206 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash); + 225 3070554 : tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash); 226 : - 227 6828628 : while (i) { + 227 6829396 : while (i) { 228 : /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ - 229 1729368 : if (i->key == hash && cmp(cmp_arg, i->data) == 0) - 230 1043152 : return i->data; - 231 686216 : i = i->next; + 229 1728517 : if (i->key == hash && cmp(cmp_arg, i->data) == 0) + 230 1040229 : return i->data; + 231 688288 : i = i->next; 232 : } - 233 2028054 : return 0; + 233 2030325 : return 0; 234 : } 235 : 236 : /** diff --git a/cov/tommyds/tommylist.c.func-sort-c.html b/cov/tommyds/tommylist.c.func-sort-c.html index 47df2c6b..50240eef 100644 --- a/cov/tommyds/tommylist.c.func-sort-c.html +++ b/cov/tommyds/tommylist.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/tommyds/tommylist.c.func.html b/cov/tommyds/tommylist.c.func.html index 5048c524..4a3655e5 100644 --- a/cov/tommyds/tommylist.c.func.html +++ b/cov/tommyds/tommylist.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 diff --git a/cov/tommyds/tommylist.c.gcov.html b/cov/tommyds/tommylist.c.gcov.html index d3fa6ea4..a3fd03cb 100644 --- a/cov/tommyds/tommylist.c.gcov.html +++ b/cov/tommyds/tommylist.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 3 @@ -97,23 +97,23 @@ 35 : tommy_node* second_head; 36 : 37 63152 : if (tommy_list_empty(second)) - 38 55852 : return; + 38 55942 : return; 39 : - 40 7300 : if (tommy_list_empty(first)) { - 41 6458 : *first = *second; - 42 6458 : return; + 40 7210 : if (tommy_list_empty(first)) { + 41 6347 : *first = *second; + 42 6347 : return; 43 : } 44 : - 45 842 : first_head = tommy_list_head(first); - 46 842 : second_head = tommy_list_head(second); - 47 842 : first_tail = tommy_list_tail(first); + 45 863 : first_head = tommy_list_head(first); + 46 863 : second_head = tommy_list_head(second); + 47 863 : first_tail = tommy_list_tail(first); 48 : 49 : /* set the "circular" prev list */ - 50 842 : first_head->prev = second_head->prev; - 51 842 : second_head->prev = first_tail; + 50 863 : first_head->prev = second_head->prev; + 51 863 : second_head->prev = first_tail; 52 : 53 : /* set the "0 terminated" next list */ - 54 842 : first_tail->next = second_head; + 54 863 : first_tail->next = second_head; 55 : } 56 : 57 : /** \internal diff --git a/cov/tommyds/tommylist.h.func-sort-c.html b/cov/tommyds/tommylist.h.func-sort-c.html index 14e25432..9c8d2d57 100644 --- a/cov/tommyds/tommylist.h.func-sort-c.html +++ b/cov/tommyds/tommylist.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -61,27 +61,27 @@ tommy_list_head - 24488891 + 24488786 tommy_list_insert_first - 22766373 + 22741744 tommy_list_insert_tail - 17766906 + 17767092 tommy_list_insert_tail_not_empty - 10676661 + 10700756 tommy_list_remove_existing - 341990 + 341445 tommy_list_empty - 74265 + 74175 tommy_list_init @@ -93,7 +93,7 @@ tommy_list_tail - 843 + 864 tommy_list_count diff --git a/cov/tommyds/tommylist.h.func.html b/cov/tommyds/tommylist.h.func.html index a2edcfa4..c10d1292 100644 --- a/cov/tommyds/tommylist.h.func.html +++ b/cov/tommyds/tommylist.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -65,7 +65,7 @@ tommy_list_empty - 74265 + 74175 tommy_list_foreach @@ -73,7 +73,7 @@ tommy_list_head - 24488891 + 24488786 tommy_list_init @@ -81,23 +81,23 @@ tommy_list_insert_first - 22766373 + 22741744 tommy_list_insert_tail - 17766906 + 17767092 tommy_list_insert_tail_not_empty - 10676661 + 10700756 tommy_list_remove_existing - 341990 + 341445 tommy_list_tail - 843 + 864
diff --git a/cov/tommyds/tommylist.h.gcov.html b/cov/tommyds/tommylist.h.gcov.html index 51fe1a93..34f2c18f 100644 --- a/cov/tommyds/tommylist.h.gcov.html +++ b/cov/tommyds/tommylist.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 10 @@ -182,23 +182,23 @@ 120 : * Gets the head of the list. 121 : * \return The head node. For empty lists 0 is returned. 122 : */ - 123 24488891 : tommy_inline tommy_node* tommy_list_head(tommy_list* list) + 123 24488786 : tommy_inline tommy_node* tommy_list_head(tommy_list* list) 124 : { - 125 24488891 : return *list; + 125 24488786 : return *list; 126 : } 127 : 128 : /** 129 : * Gets the tail of the list. 130 : * \return The tail node. For empty lists 0 is returned. 131 : */ - 132 843 : tommy_inline tommy_node* tommy_list_tail(tommy_list* list) + 132 864 : tommy_inline tommy_node* tommy_list_tail(tommy_list* list) 133 : { - 134 843 : tommy_node* head = tommy_list_head(list); + 134 864 : tommy_node* head = tommy_list_head(list); 135 : - 136 843 : if (!head) + 136 864 : if (!head) 137 1 : return 0; 138 : - 139 842 : return head->prev; + 139 863 : return head->prev; 140 : } 141 : 142 : /** \internal @@ -206,16 +206,16 @@ 144 : * \param list The list to initialize. 145 : * \param node The node to insert. 146 : */ - 147 22766373 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node) + 147 22741744 : tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node) 148 : { 149 : /* one element "circular" prev list */ - 150 22766373 : node->prev = node; + 150 22741744 : node->prev = node; 151 : 152 : /* one element "0 terminated" next list */ - 153 22766373 : node->next = 0; + 153 22741744 : node->next = 0; 154 : - 155 22766373 : *list = node; - 156 22766373 : } + 155 22741744 : *list = node; + 156 22741744 : } 157 : 158 : /** \internal 159 : * Inserts an element at the head of a not empty list. @@ -243,16 +243,16 @@ 181 : * \param head The node at the list head. It cannot be 0. 182 : * \param node The node to insert. 183 : */ - 184 10676661 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node) + 184 10700756 : tommy_inline void tommy_list_insert_tail_not_empty(tommy_node* head, tommy_node* node) 185 : { 186 : /* insert in the "circular" prev list */ - 187 10676661 : node->prev = head->prev; - 188 10676661 : head->prev = node; + 187 10700756 : node->prev = head->prev; + 188 10700756 : head->prev = node; 189 : 190 : /* insert in the "0 terminated" next list */ - 191 10676661 : node->next = 0; - 192 10676661 : node->prev->next = node; - 193 10676661 : } + 191 10700756 : node->next = 0; + 192 10700756 : node->prev->next = node; + 193 10700756 : } 194 : 195 : /** 196 : * Inserts an element at the head of a list. @@ -276,17 +276,17 @@ 214 : * \param node The node to insert. 215 : * \param data The object containing the node. It's used to set the tommy_node::data field of the node. 216 : */ - 217 17766906 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data) + 217 17767092 : tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, void* data) 218 : { - 219 17766906 : tommy_node* head = tommy_list_head(list); + 219 17767092 : tommy_node* head = tommy_list_head(list); 220 : - 221 17766906 : if (head) - 222 8816947 : tommy_list_insert_tail_not_empty(head, node); + 221 17767092 : if (head) + 222 8839895 : tommy_list_insert_tail_not_empty(head, node); 223 : else - 224 8949959 : tommy_list_insert_first(list, node); + 224 8927197 : tommy_list_insert_first(list, node); 225 : - 226 17766906 : node->data = data; - 227 17766906 : } + 226 17767092 : node->data = data; + 227 17767092 : } 228 : 229 : /** \internal 230 : * Removes an element from the head of a not empty list. @@ -314,23 +314,23 @@ 252 : * \param node The node to remove. The node must be in the list. 253 : * \return The tommy_node::data field of the node removed. 254 : */ - 255 341990 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node) + 255 341445 : tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node) 256 : { - 257 341990 : tommy_node* head = tommy_list_head(list); + 257 341445 : tommy_node* head = tommy_list_head(list); 258 : 259 : /* remove from the "circular" prev list */ - 260 341990 : if (node->next) - 261 118050 : node->next->prev = node->prev; + 260 341445 : if (node->next) + 261 118988 : node->next->prev = node->prev; 262 : else - 263 223940 : head->prev = node->prev; /* the last */ + 263 222457 : head->prev = node->prev; /* the last */ 264 : 265 : /* remove from the "0 terminated" next list */ - 266 341990 : if (head == node) - 267 241521 : *list = node->next; /* the new head, in case 0 */ + 266 341445 : if (head == node) + 267 241019 : *list = node->next; /* the new head, in case 0 */ 268 : else - 269 100469 : node->prev->next = node->next; + 269 100426 : node->prev->next = node->next; 270 : - 271 341990 : return node->data; + 271 341445 : return node->data; 272 : } 273 : 274 : /** @@ -355,9 +355,9 @@ 293 : * Checks if empty. 294 : * \return If the list is empty. 295 : */ - 296 74265 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) + 296 74175 : tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) 297 : { - 298 74265 : return tommy_list_head(list) == 0; + 298 74175 : return tommy_list_head(list) == 0; 299 : } 300 : 301 : /** @@ -409,10 +409,10 @@ 347 : { 348 7071 : tommy_node* node = tommy_list_head(list); 349 : - 350 3547290 : while (node) { - 351 3533148 : void* data = node->data; - 352 3533148 : node = node->next; - 353 3533148 : func(data); + 350 3547533 : while (node) { + 351 3533391 : void* data = node->data; + 352 3533391 : node = node->next; + 353 3533391 : func(data); 354 : } 355 7071 : } 356 : diff --git a/cov/tommyds/tommytree.c.func-sort-c.html b/cov/tommyds/tommytree.c.func-sort-c.html index 495ac6d7..b79d2f99 100644 --- a/cov/tommyds/tommytree.c.func-sort-c.html +++ b/cov/tommyds/tommytree.c.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 19 @@ -61,55 +61,55 @@ tommy_tree_search_node - 325769250 + 324348165 tommy_tree_delta - 108654608 + 108663041 tommy_tree_balance - 101404691 + 101410069 tommy_tree_insert_node - 93001944 + 93001793 tommy_tree_search_compare - 31419339 + 31336465 tommy_tree_foreach_arg_node - 25170953 + 25171385 tommy_tree_rotate_left - 7239414 + 7241652 tommy_tree_insert - 7215863 + 7215779 tommy_tree_foreach_node - 6799122 + 6799230 tommy_tree_remove_node - 774936 + 775421 tommy_tree_move_right - 181790 + 183618 tommy_tree_rotate_right - 169440 + 168850 tommy_tree_remove - 77976 + 78058 tommy_tree_foreach_arg diff --git a/cov/tommyds/tommytree.c.func.html b/cov/tommyds/tommytree.c.func.html index af462197..c84d6f4c 100644 --- a/cov/tommyds/tommytree.c.func.html +++ b/cov/tommyds/tommytree.c.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 19 @@ -61,11 +61,11 @@ tommy_tree_balance - 101404691 + 101410069 tommy_tree_delta - 108654608 + 108663041 tommy_tree_foreach @@ -77,11 +77,11 @@ tommy_tree_foreach_arg_node - 25170953 + 25171385 tommy_tree_foreach_node - 6799122 + 6799230 tommy_tree_init @@ -89,11 +89,11 @@ tommy_tree_insert - 7215863 + 7215779 tommy_tree_insert_node - 93001944 + 93001793 tommy_tree_memory_usage @@ -101,11 +101,11 @@ tommy_tree_move_right - 181790 + 183618 tommy_tree_remove - 77976 + 78058 tommy_tree_remove_existing @@ -113,15 +113,15 @@ tommy_tree_remove_node - 774936 + 775421 tommy_tree_rotate_left - 7239414 + 7241652 tommy_tree_rotate_right - 169440 + 168850 tommy_tree_search @@ -129,11 +129,11 @@ tommy_tree_search_compare - 31419339 + 31336465 tommy_tree_search_node - 325769250 + 324348165
diff --git a/cov/tommyds/tommytree.c.gcov.html b/cov/tommyds/tommytree.c.gcov.html index 1b25a859..4658bf45 100644 --- a/cov/tommyds/tommytree.c.gcov.html +++ b/cov/tommyds/tommytree.c.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 19 @@ -101,97 +101,97 @@ 39 2955 : tree->cmp = cmp; 40 2955 : } 41 : - 42 108654608 : static int tommy_tree_delta(tommy_tree_node* root) + 42 108663041 : static int tommy_tree_delta(tommy_tree_node* root) 43 : { - 44 108654608 : int left_height = root->prev ? root->prev->key : 0; - 45 108654608 : int right_height = root->next ? root->next->key : 0; + 44 108663041 : int left_height = root->prev ? root->prev->key : 0; + 45 108663041 : int right_height = root->next ? root->next->key : 0; 46 : - 47 108654608 : return left_height - right_height; + 47 108663041 : return left_height - right_height; 48 : } 49 : 50 : /* AVL tree operations */ 51 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node*); 52 : - 53 7239414 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root) + 53 7241652 : static tommy_tree_node* tommy_tree_rotate_left(tommy_tree_node* root) 54 : { - 55 7239414 : tommy_tree_node* next = root->next; + 55 7241652 : tommy_tree_node* next = root->next; 56 : - 57 7239414 : root->next = next->prev; + 57 7241652 : root->next = next->prev; 58 : - 59 7239414 : next->prev = tommy_tree_balance(root); + 59 7241652 : next->prev = tommy_tree_balance(root); 60 : - 61 7239414 : return tommy_tree_balance(next); + 61 7241652 : return tommy_tree_balance(next); 62 : } 63 : - 64 169440 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root) + 64 168850 : static tommy_tree_node* tommy_tree_rotate_right(tommy_tree_node* root) 65 : { - 66 169440 : tommy_tree_node* prev = root->prev; + 66 168850 : tommy_tree_node* prev = root->prev; 67 : - 68 169440 : root->prev = prev->next; + 68 168850 : root->prev = prev->next; 69 : - 70 169440 : prev->next = tommy_tree_balance(root); + 70 168850 : prev->next = tommy_tree_balance(root); 71 : - 72 169440 : return tommy_tree_balance(prev); + 72 168850 : return tommy_tree_balance(prev); 73 : } 74 : - 75 181790 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node) + 75 183618 : static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_node* node) 76 : { - 77 181790 : if (!root) - 78 77848 : return node; + 77 183618 : if (!root) + 78 77930 : return node; 79 : - 80 103942 : root->next = tommy_tree_move_right(root->next, node); + 80 105688 : root->next = tommy_tree_move_right(root->next, node); 81 : - 82 103942 : return tommy_tree_balance(root); + 82 105688 : return tommy_tree_balance(root); 83 : } 84 : - 85 101404691 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root) + 85 101410069 : static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root) 86 : { - 87 101404691 : int delta = tommy_tree_delta(root); + 87 101410069 : int delta = tommy_tree_delta(root); 88 : - 89 101404691 : if (delta < -1) { - 90 7121472 : if (tommy_tree_delta(root->next) > 0) - 91 40995 : root->next = tommy_tree_rotate_right(root->next); - 92 7121472 : return tommy_tree_rotate_left(root); + 89 101410069 : if (delta < -1) { + 90 7125675 : if (tommy_tree_delta(root->next) > 0) + 91 41553 : root->next = tommy_tree_rotate_right(root->next); + 92 7125675 : return tommy_tree_rotate_left(root); 93 : } 94 : - 95 94283219 : if (delta > 1) { - 96 128445 : if (tommy_tree_delta(root->prev) < 0) - 97 117942 : root->prev = tommy_tree_rotate_left(root->prev); - 98 128445 : return tommy_tree_rotate_right(root); + 95 94284394 : if (delta > 1) { + 96 127297 : if (tommy_tree_delta(root->prev) < 0) + 97 115977 : root->prev = tommy_tree_rotate_left(root->prev); + 98 127297 : return tommy_tree_rotate_right(root); 99 : } 100 : 101 : /* recompute key */ - 102 94154774 : root->key = 0; + 102 94157097 : root->key = 0; 103 : - 104 94154774 : if (root->prev && root->prev->key > root->key) - 105 76186657 : root->key = root->prev->key; + 104 94157097 : if (root->prev && root->prev->key > root->key) + 105 76188949 : root->key = root->prev->key; 106 : - 107 94154774 : if (root->next && root->next->key > root->key) - 108 43398384 : root->key = root->next->key; + 107 94157097 : if (root->next && root->next->key > root->key) + 108 43401597 : root->key = root->next->key; 109 : 110 : /* count itself */ - 111 94154774 : root->key += 1; + 111 94157097 : root->key += 1; 112 : - 113 94154774 : return root; + 113 94157097 : return root; 114 : } 115 : - 116 93001944 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let) + 116 93001793 : static tommy_tree_node* tommy_tree_insert_node(tommy_compare_func* cmp, tommy_tree_node* root, tommy_tree_node** let) 117 : { 118 : int c; 119 : - 120 93001944 : if (!root) - 121 7215862 : return *let; + 120 93001793 : if (!root) + 121 7215778 : return *let; 122 : - 123 85786082 : c = cmp((*let)->data, root->data); + 123 85786015 : c = cmp((*let)->data, root->data); 124 : - 125 85786082 : if (c < 0) { - 126 1489892 : root->prev = tommy_tree_insert_node(cmp, root->prev, let); - 127 1489892 : return tommy_tree_balance(root); + 125 85786015 : if (c < 0) { + 126 1492912 : root->prev = tommy_tree_insert_node(cmp, root->prev, let); + 127 1492912 : return tommy_tree_balance(root); 128 : } 129 : - 130 84296190 : if (c > 0) { - 131 84296189 : root->next = tommy_tree_insert_node(cmp, root->next, let); - 132 84296189 : return tommy_tree_balance(root); + 130 84293103 : if (c > 0) { + 131 84293102 : root->next = tommy_tree_insert_node(cmp, root->next, let); + 132 84293102 : return tommy_tree_balance(root); 133 : } 134 : 135 : /* already present, set the return pointer */ @@ -200,78 +200,78 @@ 138 1 : return root; 139 : } 140 : - 141 7215863 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data) + 141 7215779 : void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data) 142 : { - 143 7215863 : tommy_tree_node* insert = node; + 143 7215779 : tommy_tree_node* insert = node; 144 : - 145 7215863 : insert->data = data; - 146 7215863 : insert->prev = 0; - 147 7215863 : insert->next = 0; - 148 7215863 : insert->key = 0; + 145 7215779 : insert->data = data; + 146 7215779 : insert->prev = 0; + 147 7215779 : insert->next = 0; + 148 7215779 : insert->key = 0; 149 : - 150 7215863 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert); + 150 7215779 : tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert); 151 : - 152 7215863 : if (insert == node) - 153 7215862 : ++tree->count; + 152 7215779 : if (insert == node) + 153 7215778 : ++tree->count; 154 : - 155 7215863 : return node->data; + 155 7215779 : return node->data; 156 : } 157 : - 158 774936 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let) + 158 775421 : static tommy_tree_node* tommy_tree_remove_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data, tommy_tree_node** let) 159 : { 160 : int c; 161 : - 162 774936 : if (!root) + 162 775421 : if (!root) 163 128 : return 0; 164 : - 165 774808 : c = cmp(data, root->data); + 165 775293 : c = cmp(data, root->data); 166 : - 167 774808 : if (c < 0) { - 168 299059 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let); - 169 299059 : return tommy_tree_balance(root); + 167 775293 : if (c < 0) { + 168 298766 : root->prev = tommy_tree_remove_node(cmp, root->prev, data, let); + 169 298766 : return tommy_tree_balance(root); 170 : } 171 : - 172 475749 : if (c > 0) { - 173 397901 : root->next = tommy_tree_remove_node(cmp, root->next, data, let); - 174 397901 : return tommy_tree_balance(root); + 172 476527 : if (c > 0) { + 173 398597 : root->next = tommy_tree_remove_node(cmp, root->next, data, let); + 174 398597 : return tommy_tree_balance(root); 175 : } 176 : 177 : /* found */ - 178 77848 : *let = root; + 178 77930 : *let = root; 179 : - 180 77848 : return tommy_tree_move_right(root->prev, root->next); + 180 77930 : return tommy_tree_move_right(root->prev, root->next); 181 : } 182 : - 183 77976 : void* tommy_tree_remove(tommy_tree* tree, void* data) + 183 78058 : void* tommy_tree_remove(tommy_tree* tree, void* data) 184 : { - 185 77976 : tommy_tree_node* node = 0; + 185 78058 : tommy_tree_node* node = 0; 186 : - 187 77976 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node); + 187 78058 : tree->root = tommy_tree_remove_node(tree->cmp, tree->root, data, &node); 188 : - 189 77976 : if (!node) + 189 78058 : if (!node) 190 128 : return 0; 191 : - 192 77848 : --tree->count; + 192 77930 : --tree->count; 193 : - 194 77848 : return node->data; + 194 77930 : return node->data; 195 : } 196 : - 197 325769250 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data) + 197 324348165 : static tommy_tree_node* tommy_tree_search_node(tommy_compare_func* cmp, tommy_tree_node* root, void* data) 198 : { 199 : int c; 200 : - 201 325769250 : if (!root) - 202 2357034 : return 0; + 201 324348165 : if (!root) + 202 2354776 : return 0; 203 : - 204 323412216 : c = cmp(data, root->data); + 204 321993389 : c = cmp(data, root->data); 205 : - 206 331008984 : if (c < 0) - 207 130163691 : return tommy_tree_search_node(cmp, root->prev, data); + 206 330820889 : if (c < 0) + 207 130151880 : return tommy_tree_search_node(cmp, root->prev, data); 208 : - 209 200845293 : if (c > 0) - 210 171813618 : return tommy_tree_search_node(cmp, root->next, data); + 209 200669009 : if (c > 0) + 210 171722863 : return tommy_tree_search_node(cmp, root->next, data); 211 : - 212 29031675 : return root; + 212 28946146 : return root; 213 : } 214 : 215 2 : void* tommy_tree_search(tommy_tree* tree, void* data) @@ -284,14 +284,14 @@ 222 1 : return node->data; 223 : } 224 : - 225 31419339 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg) + 225 31336465 : void* tommy_tree_search_compare(tommy_tree* tree, tommy_compare_func* cmp, void* cmp_arg) 226 : { - 227 31419339 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg); + 227 31336465 : tommy_tree_node* node = tommy_tree_search_node(cmp, tree->root, cmp_arg); 228 : - 229 31233438 : if (!node) - 230 2356966 : return 0; + 229 31273364 : if (!node) + 230 2346177 : return 0; 231 : - 232 28876472 : return node->data; + 232 28927187 : return node->data; 233 : } 234 : 235 128 : void* tommy_tree_remove_existing(tommy_tree* tree, tommy_tree_node* node) @@ -303,21 +303,21 @@ 241 128 : return data; 242 : } 243 : - 244 6799122 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func) + 244 6799230 : static void tommy_tree_foreach_node(tommy_tree_node* root, tommy_foreach_func* func) 245 : { 246 : tommy_tree_node* next; 247 : - 248 6799122 : if (!root) - 249 10199359 : return; + 248 6799230 : if (!root) + 249 10199521 : return; 250 : - 251 3398885 : tommy_tree_foreach_node(root->prev, func); + 251 3398939 : tommy_tree_foreach_node(root->prev, func); 252 : 253 : /* make a copy in case func is free() */ - 254 3398885 : next = root->next; + 254 3398939 : next = root->next; 255 : - 256 3398885 : func(root->data); + 256 3398939 : func(root->data); 257 : - 258 3398885 : tommy_tree_foreach_node(next, func); + 258 3398939 : tommy_tree_foreach_node(next, func); 259 : } 260 : 261 1352 : void tommy_tree_foreach(tommy_tree* tree, tommy_foreach_func* func) @@ -325,21 +325,21 @@ 263 1352 : tommy_tree_foreach_node(tree->root, func); 264 1352 : } 265 : - 266 25170953 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg) + 266 25171385 : static void tommy_tree_foreach_arg_node(tommy_tree_node* root, tommy_foreach_arg_func* func, void* arg) 267 : { 268 : tommy_tree_node* next; 269 : - 270 25170953 : if (!root) - 271 37759106 : return; + 270 25171385 : if (!root) + 271 37759754 : return; 272 : - 273 12582800 : tommy_tree_foreach_arg_node(root->prev, func, arg); + 273 12583016 : tommy_tree_foreach_arg_node(root->prev, func, arg); 274 : 275 : /* make a copy in case func is free() */ - 276 12582800 : next = root->next; + 276 12583016 : next = root->next; 277 : - 278 12582800 : func(arg, root->data); + 278 12583016 : func(arg, root->data); 279 : - 280 12582800 : tommy_tree_foreach_arg_node(next, func, arg); + 280 12583016 : tommy_tree_foreach_arg_node(next, func, arg); 281 : } 282 : 283 5353 : void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void* arg) diff --git a/cov/tommyds/tommytree.h.func-sort-c.html b/cov/tommyds/tommytree.h.func-sort-c.html index 7d920651..402c3c72 100644 --- a/cov/tommyds/tommytree.h.func-sort-c.html +++ b/cov/tommyds/tommytree.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/tommyds/tommytree.h.func.html b/cov/tommyds/tommytree.h.func.html index e540b6ba..6566356b 100644 --- a/cov/tommyds/tommytree.h.func.html +++ b/cov/tommyds/tommytree.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/tommyds/tommytree.h.gcov.html b/cov/tommyds/tommytree.h.gcov.html index 46d24eeb..ec3ff04a 100644 --- a/cov/tommyds/tommytree.h.gcov.html +++ b/cov/tommyds/tommytree.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 1 diff --git a/cov/tommyds/tommytypes.h.func-sort-c.html b/cov/tommyds/tommytypes.h.func-sort-c.html index 2dd7628d..5b79e95e 100644 --- a/cov/tommyds/tommytypes.h.func-sort-c.html +++ b/cov/tommyds/tommytypes.h.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -61,7 +61,7 @@ tommy_ilog2_u32 - 15274023 + 15297694 tommy_ctz_u32 diff --git a/cov/tommyds/tommytypes.h.func.html b/cov/tommyds/tommytypes.h.func.html index 9eb1778e..e495be7b 100644 --- a/cov/tommyds/tommytypes.h.func.html +++ b/cov/tommyds/tommytypes.h.func.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -65,7 +65,7 @@ tommy_ilog2_u32 - 15274023 + 15297694
diff --git a/cov/tommyds/tommytypes.h.gcov.html b/cov/tommyds/tommytypes.h.gcov.html index 55888cfb..018a04b9 100644 --- a/cov/tommyds/tommytypes.h.gcov.html +++ b/cov/tommyds/tommytypes.h.gcov.html @@ -37,7 +37,7 @@ Date: - 2015-11-13 + 2015-11-20 Functions: 2 @@ -385,7 +385,7 @@ 323 : * \param value Value to scan. 0 is not allowed. 324 : * \return The index of the most significant bit set. 325 : */ - 326 15274023 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) + 326 15297694 : tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) 327 : { 328 : #if defined(_MSC_VER) 329 : unsigned long count; @@ -401,7 +401,7 @@ 339 : * So we write "__builtin_clz(x) ^ 31" instead of "31 - __builtin_clz(x)", 340 : * to allow the double xor to be optimized out. 341 : */ - 342 15274023 : return __builtin_clz(value) ^ 31; + 342 15297694 : return __builtin_clz(value) ^ 31; 343 : #else 344 : /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */ 345 : /* from http://graphics.stanford.edu/~seander/bithacks.html */ diff --git a/download.html b/download.html index 88338e53..6cc52373 100644 --- a/download.html +++ b/download.html @@ -50,17 +50,17 @@ If you like to use a GUI, you can try E diff --git a/index.html b/index.html index 8221a15f..c9aebd45 100644 --- a/index.html +++ b/index.html @@ -86,7 +86,7 @@ Now go to Download.

-News! Version 9.0 RETIRED! SEE THIS FOR DETAILS! +News! Version 9.1 RELEASED!

FileDescription
-snapraid-8.1.tar.gz +snapraid-9.1.tar.gz Sources for Linux, Mac OS X, BSD, Solaris, OpenIndiana and any other Unix
-snapraid-8.1-windows-x64.zip +snapraid-9.1-windows-x64.zip Binaries for Windows x64 (the most recent Windows versions)
-snapraid-8.1-windows-x86.zip +snapraid-9.1-windows-x86.zip Binaries for Windows x86