Line data Source code
1 : // SPDX-License-Identifier: GPL-3.0-or-later 2 : // Copyright (C) 2013 Andrea Mazzoleni 3 : 4 : #include "portable.h" 5 : 6 : #include "util.h" 7 : #include "elem.h" 8 : #include "import.h" 9 : #include "state.h" 10 : #include "parity.h" 11 : #include "handle.h" 12 : #include "raid/raid.h" 13 : 14 : /****************************************************************************/ 15 : /* rehash */ 16 : 17 1 : void state_rehash(struct snapraid_state* state) 18 : { 19 : block_off_t blockmax; 20 : block_off_t i; 21 : 22 1 : blockmax = parity_allocated_size(state); 23 : 24 : /* check if a rehash is already in progress */ 25 1 : if (state->prevhash != HASH_UNDEFINED) { 26 : /* LCOV_EXCL_START */ 27 : log_tag("summary:exit:already_in_progress\n"); 28 : log_fatal(EUSER, "You already have a rehash in progress.\n"); 29 : exit(EXIT_FAILURE); 30 : /* LCOV_EXCL_STOP */ 31 : } 32 : 33 1 : if (state->hash == state->besthash) { 34 : /* LCOV_EXCL_START */ 35 : log_tag("summary:exit:not_required\n"); 36 : log_fatal(EUSER, "You are already using the best hash for your platform.\n"); 37 : exit(EXIT_FAILURE); 38 : /* LCOV_EXCL_STOP */ 39 : } 40 : 41 : /* copy the present hash as previous one */ 42 1 : state->prevhash = state->hash; 43 1 : memcpy(state->prevhashseed, state->hashseed, HASH_MAX); 44 : 45 : /* set the new hash and seed */ 46 1 : state->hash = state->besthash; 47 1 : if (randomize(state->hashseed, HASH_MAX) != 0) { 48 : /* LCOV_EXCL_START */ 49 : log_fatal(errno, "Failed to get random values.\n"); 50 : exit(EXIT_FAILURE); 51 : /* LCOV_EXCL_STOP */ 52 : } 53 : 54 : /* mark all the block for rehashing */ 55 9276 : for (i = 0; i < blockmax; ++i) { 56 : snapraid_info info; 57 : 58 : /* if it's unused */ 59 9275 : info = info_get(&state->infoarr, i); 60 9275 : if (info == 0) { 61 : /* skip it */ 62 0 : continue; 63 : } 64 : 65 9275 : if (info_get_rehash(info)) { 66 : /* LCOV_EXCL_START */ 67 : log_fatal(EINTERNAL, "Internal inconsistency for a rehash already in progress\n"); 68 : os_abort(); 69 : /* LCOV_EXCL_STOP */ 70 : } 71 : 72 : /* enable the rehash */ 73 9275 : info = info_set_rehash(info); 74 : 75 : /* save it */ 76 9275 : info_set(&state->infoarr, i, info); 77 : } 78 : 79 : /* save the new content file */ 80 1 : state->need_write = 1; 81 : 82 1 : msg_status("A rehash is now scheduled. It will take place progressively in the next\n"); 83 1 : msg_status("'sync' and 'scrub' commands. You can check the rehash progress using the\n"); 84 1 : msg_status("'status' command.\n"); 85 1 : log_tag("summary:exit:scheduled\n"); 86 1 : } 87 :