2011-03-01 22:19:30 +01:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
< html lang = "en" >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
< title > LCOV - lcov.info - cmdline/sync.c< / title >
< link rel = "stylesheet" type = "text/css" href = "../gcov.css" >
< / head >
< body >
< table width = "100%" border = 0 cellspacing = 0 cellpadding = 0 >
< tr > < td class = "title" > LCOV - code coverage report< / td > < / tr >
< tr > < td class = "ruler" > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
< tr >
< td width = "100%" >
< table cellpadding = 1 border = 0 width = "100%" >
< tr >
< td width = "10%" class = "headerItem" > Current view:< / td >
2017-12-11 23:00:27 +01:00
< td width = "35%" class = "headerValue" > < a href = "../index.html" > top level< / a > - < a href = "index.html" > cmdline< / a > - sync.c< span style = "font-size: 80%;" > (source / < a href = "sync.c.func-sort-c.html" > functions< / a > )< / span > < / td >
2011-03-01 22:19:30 +01:00
< td width = "5%" > < / td >
< td width = "15%" > < / td >
< td width = "10%" class = "headerCovTableHead" > Hit< / td >
< td width = "10%" class = "headerCovTableHead" > Total< / td >
< td width = "15%" class = "headerCovTableHead" > Coverage< / td >
< / tr >
< tr >
< td class = "headerItem" > Test:< / td >
< td class = "headerValue" > lcov.info< / td >
< td > < / td >
< td class = "headerItem" > Lines:< / td >
2026-02-28 09:59:35 +01:00
< td class = "headerCovTableEntry" > 514< / td >
< td class = "headerCovTableEntry" > 572< / td >
< td class = "headerCovTableEntryMed" > 89.9 %< / td >
2011-03-01 22:19:30 +01:00
< / tr >
< tr >
< td class = "headerItem" > Date:< / td >
2026-03-15 18:52:43 +01:00
< td class = "headerValue" > 2026-03-15 15:58:19< / td >
2011-03-01 22:19:30 +01:00
< td > < / td >
< td class = "headerItem" > Functions:< / td >
2026-02-28 09:59:35 +01:00
< td class = "headerCovTableEntry" > 8< / td >
< td class = "headerCovTableEntry" > 8< / td >
2011-03-01 22:19:30 +01:00
< td class = "headerCovTableEntryHi" > 100.0 %< / td >
< / tr >
< tr > < td > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
< / table >
< / td >
< / tr >
< tr > < td class = "ruler" > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
< / table >
< table cellpadding = 0 cellspacing = 0 border = 0 >
< tr >
< td > < br > < / td >
< / tr >
< tr >
< td >
< pre class = "sourceHeading" > Line data Source code< / pre >
< pre class = "source" >
< a name = "1" > < span class = "lineNum" > 1 < / span > : /*< / a >
2025-10-28 12:01:21 +01:00
< a name = "2" > < span class = "lineNum" > 2 < / span > : * Copyright (C) 2011 Andrea Mazzoleni< / a >
< a name = "3" > < span class = "lineNum" > 3 < / span > : *< / a >
< a name = "4" > < span class = "lineNum" > 4 < / span > : * This program is free software: you can redistribute it and/or modify< / a >
< a name = "5" > < span class = "lineNum" > 5 < / span > : * it under the terms of the GNU General Public License as published by< / a >
< a name = "6" > < span class = "lineNum" > 6 < / span > : * the Free Software Foundation, either version 3 of the License, or< / a >
< a name = "7" > < span class = "lineNum" > 7 < / span > : * (at your option) any later version.< / a >
< a name = "8" > < span class = "lineNum" > 8 < / span > : *< / a >
< a name = "9" > < span class = "lineNum" > 9 < / span > : * This program is distributed in the hope that it will be useful,< / a >
< a name = "10" > < span class = "lineNum" > 10 < / span > : * but WITHOUT ANY WARRANTY; without even the implied warranty of< / a >
< a name = "11" > < span class = "lineNum" > 11 < / span > : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the< / a >
< a name = "12" > < span class = "lineNum" > 12 < / span > : * GNU General Public License for more details.< / a >
< a name = "13" > < span class = "lineNum" > 13 < / span > : *< / a >
< a name = "14" > < span class = "lineNum" > 14 < / span > : * You should have received a copy of the GNU General Public License< / a >
< a name = "15" > < span class = "lineNum" > 15 < / span > : * along with this program. If not, see < http://www.gnu.org/licenses/> .< / a >
< a name = "16" > < span class = "lineNum" > 16 < / span > : */< / a >
< a name = "17" > < span class = "lineNum" > 17 < / span > : < / a >
< a name = "18" > < span class = "lineNum" > 18 < / span > : #include " portable.h" < / a >
< a name = "19" > < span class = "lineNum" > 19 < / span > : < / a >
< a name = "20" > < span class = "lineNum" > 20 < / span > : #include " support.h" < / a >
< a name = "21" > < span class = "lineNum" > 21 < / span > : #include " elem.h" < / a >
< a name = "22" > < span class = "lineNum" > 22 < / span > : #include " state.h" < / a >
< a name = "23" > < span class = "lineNum" > 23 < / span > : #include " parity.h" < / a >
< a name = "24" > < span class = "lineNum" > 24 < / span > : #include " handle.h" < / a >
< a name = "25" > < span class = "lineNum" > 25 < / span > : #include " io.h" < / a >
< a name = "26" > < span class = "lineNum" > 26 < / span > : #include " raid/raid.h" < / a >
< a name = "27" > < span class = "lineNum" > 27 < / span > : < / a >
< a name = "28" > < span class = "lineNum" > 28 < / span > : /****************************************************************************/< / a >
2016-11-06 18:12:17 +01:00
< a name = "29" > < span class = "lineNum" > 29 < / span > : /* hash */< / a >
2025-10-28 12:01:21 +01:00
< a name = "30" > < span class = "lineNum" > 30 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "31" > < span class = "lineNum" > 31 < / span > < span class = "lineCov" > 18 : static const char* es(int err)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "32" > < span class = "lineNum" > 32 < / span > : {< / a >
2026-02-28 09:59:35 +01:00
< a name = "33" > < span class = "lineNum" > 33 < / span > < span class = "lineCov" > 18 : if (is_hw(err))< / span > < / a >
< a name = "34" > < span class = "lineNum" > 34 < / span > < span class = "lineNoCov" > 0 : return " error_io" ;< / span > < / a >
< a name = "35" > < span class = "lineNum" > 35 < / span > : else< / a >
< a name = "36" > < span class = "lineNum" > 36 < / span > < span class = "lineCov" > 18 : return " error" ;< / span > < / a >
< a name = "37" > < span class = "lineNum" > 37 < / span > : }< / a >
< a name = "38" > < span class = "lineNum" > 38 < / span > : < / a >
< a name = "39" > < span class = "lineNum" > 39 < / span > < span class = "lineCov" > 7 : static int state_hash_process(struct snapraid_state* state, block_off_t blockstart, block_off_t blockmax, int* skip_sync)< / span > < / a >
< a name = "40" > < span class = "lineNum" > 40 < / span > : {< / a >
< a name = "41" > < span class = "lineNum" > 41 < / span > : struct snapraid_handle* handle;< / a >
< a name = "42" > < span class = "lineNum" > 42 < / span > : unsigned diskmax;< / a >
< a name = "43" > < span class = "lineNum" > 43 < / span > : block_off_t blockcur;< / a >
< a name = "44" > < span class = "lineNum" > 44 < / span > : unsigned j;< / a >
< a name = "45" > < span class = "lineNum" > 45 < / span > : void* buffer;< / a >
< a name = "46" > < span class = "lineNum" > 46 < / span > : void* buffer_alloc;< / a >
< a name = "47" > < span class = "lineNum" > 47 < / span > : data_off_t countsize;< / a >
< a name = "48" > < span class = "lineNum" > 48 < / span > : block_off_t countpos;< / a >
< a name = "49" > < span class = "lineNum" > 49 < / span > : block_off_t countmax;< / a >
< a name = "50" > < span class = "lineNum" > 50 < / span > : int ret;< / a >
< a name = "51" > < span class = "lineNum" > 51 < / span > : unsigned soft_error;< / a >
< a name = "52" > < span class = "lineNum" > 52 < / span > : unsigned silent_error;< / a >
< a name = "53" > < span class = "lineNum" > 53 < / span > : unsigned io_error;< / a >
< a name = "54" > < span class = "lineNum" > 54 < / span > : char esc_buffer[ESC_MAX];< / a >
2025-10-28 12:01:21 +01:00
< a name = "55" > < span class = "lineNum" > 55 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "56" > < span class = "lineNum" > 56 < / span > : /* maps the disks to handles */< / a >
< a name = "57" > < span class = "lineNum" > 57 < / span > < span class = "lineCov" > 7 : handle = handle_mapping(state, & diskmax);< / span > < / a >
< a name = "58" > < span class = "lineNum" > 58 < / span > : < / a >
< a name = "59" > < span class = "lineNum" > 59 < / span > : /* buffer for reading */< / a >
< a name = "60" > < span class = "lineNum" > 60 < / span > < span class = "lineCov" > 7 : buffer = malloc_nofail_direct(state-> block_size, & buffer_alloc);< / span > < / a >
< a name = "61" > < span class = "lineNum" > 61 < / span > < span class = "lineCov" > 7 : if (!state-> opt.skip_self)< / span > < / a >
< a name = "62" > < span class = "lineNum" > 62 < / span > < span class = "lineNoCov" > 0 : mtest_vector(1, state-> block_size, & buffer);< / span > < / a >
< a name = "63" > < span class = "lineNum" > 63 < / span > : < / a >
< a name = "64" > < span class = "lineNum" > 64 < / span > < span class = "lineCov" > 7 : soft_error = 0;< / span > < / a >
< a name = "65" > < span class = "lineNum" > 65 < / span > < span class = "lineCov" > 7 : silent_error = 0;< / span > < / a >
< a name = "66" > < span class = "lineNum" > 66 < / span > < span class = "lineCov" > 7 : io_error = 0;< / span > < / a >
< a name = "67" > < span class = "lineNum" > 67 < / span > : < / a >
< a name = "68" > < span class = "lineNum" > 68 < / span > : /* first count the number of blocks to process */< / a >
< a name = "69" > < span class = "lineNum" > 69 < / span > < span class = "lineCov" > 7 : countmax = 0;< / span > < / a >
< a name = "70" > < span class = "lineNum" > 70 < / span > < span class = "lineCov" > 49 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
< a name = "71" > < span class = "lineNum" > 71 < / span > < span class = "lineCov" > 42 : struct snapraid_disk* disk = handle[j].disk;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "72" > < span class = "lineNum" > 72 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "73" > < span class = "lineNum" > 73 < / span > : /* if no disk, nothing to check */< / a >
< a name = "74" > < span class = "lineNum" > 74 < / span > < span class = "lineCov" > 42 : if (!disk)< / span > < / a >
< a name = "75" > < span class = "lineNum" > 75 < / span > < span class = "lineNoCov" > 0 : continue;< / span > < / a >
< a name = "76" > < span class = "lineNum" > 76 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "77" > < span class = "lineNum" > 77 < / span > < span class = "lineCov" > 236706 : for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "78" > < span class = "lineNum" > 78 < / span > : struct snapraid_block* block;< / a >
< a name = "79" > < span class = "lineNum" > 79 < / span > : unsigned block_state;< / a >
< a name = "80" > < span class = "lineNum" > 80 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "81" > < span class = "lineNum" > 81 < / span > < span class = "lineCov" > 236664 : block = fs_par2block_find(disk, blockcur);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "82" > < span class = "lineNum" > 82 < / span > : < / a >
< a name = "83" > < span class = "lineNum" > 83 < / span > : /* get the state of the block */< / a >
2026-02-28 16:47:55 +01:00
< a name = "84" > < span class = "lineNum" > 84 < / span > < span class = "lineCov" > 236664 : block_state = block_state_get(block);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "85" > < span class = "lineNum" > 85 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "86" > < span class = "lineNum" > 86 < / span > : /* process REP and CHG blocks */< / a >
2026-02-28 16:47:55 +01:00
< a name = "87" > < span class = "lineNum" > 87 < / span > < span class = "lineCov" > 236664 : if (block_state != BLOCK_STATE_REP & & block_state != BLOCK_STATE_CHG)< / span > < / a >
< a name = "88" > < span class = "lineNum" > 88 < / span > < span class = "lineCov" > 223625 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "89" > < span class = "lineNum" > 89 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "90" > < span class = "lineNum" > 90 < / span > < span class = "lineCov" > 13039 : ++countmax;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "91" > < span class = "lineNum" > 91 < / span > : }< / a >
< a name = "92" > < span class = "lineNum" > 92 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "93" > < span class = "lineNum" > 93 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "94" > < span class = "lineNum" > 94 < / span > : /* drop until now */< / a >
< a name = "95" > < span class = "lineNum" > 95 < / span > < span class = "lineCov" > 7 : state_usage_waste(state);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "96" > < span class = "lineNum" > 96 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "97" > < span class = "lineNum" > 97 < / span > < span class = "lineCov" > 7 : countsize = 0;< / span > < / a >
< a name = "98" > < span class = "lineNum" > 98 < / span > < span class = "lineCov" > 7 : countpos = 0;< / span > < / a >
< a name = "99" > < span class = "lineNum" > 99 < / span > < span class = "lineCov" > 7 : blockcur = blockstart;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "100" > < span class = "lineNum" > 100 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "101" > < span class = "lineNum" > 101 < / span > < span class = "lineCov" > 7 : int alert = state_progress_begin(state, blockstart, blockmax, countmax);< / span > < / a >
< a name = "102" > < span class = "lineNum" > 102 < / span > < span class = "lineCov" > 7 : if (alert > 0)< / span > < / a >
< a name = "103" > < span class = "lineNum" > 103 < / span > < span class = "lineNoCov" > 0 : goto end;< / span > < / a >
< a name = "104" > < span class = "lineNum" > 104 < / span > < span class = "lineCov" > 7 : if (alert < 0)< / span > < / a >
< a name = "105" > < span class = "lineNum" > 105 < / span > < span class = "lineNoCov" > 0 : goto bail;< / span > < / a >
< a name = "106" > < span class = "lineNum" > 106 < / span > : < / a >
< a name = "107" > < span class = "lineNum" > 107 < / span > < span class = "lineCov" > 49 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
< a name = "108" > < span class = "lineNum" > 108 < / span > < span class = "lineCov" > 42 : struct snapraid_disk* disk = handle[j].disk;< / span > < / a >
< a name = "109" > < span class = "lineNum" > 109 < / span > : < / a >
< a name = "110" > < span class = "lineNum" > 110 < / span > : /* if no disk, nothing to check */< / a >
< a name = "111" > < span class = "lineNum" > 111 < / span > < span class = "lineCov" > 42 : if (!disk)< / span > < / a >
< a name = "112" > < span class = "lineNum" > 112 < / span > < span class = "lineNoCov" > 0 : continue;< / span > < / a >
< a name = "113" > < span class = "lineNum" > 113 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "114" > < span class = "lineNum" > 114 < / span > < span class = "lineCov" > 236706 : for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "115" > < span class = "lineNum" > 115 < / span > : snapraid_info info;< / a >
< a name = "116" > < span class = "lineNum" > 116 < / span > : int rehash;< / a >
< a name = "117" > < span class = "lineNum" > 117 < / span > : struct snapraid_block* block;< / a >
< a name = "118" > < span class = "lineNum" > 118 < / span > : int read_size;< / a >
< a name = "119" > < span class = "lineNum" > 119 < / span > : unsigned char hash[HASH_MAX];< / a >
< a name = "120" > < span class = "lineNum" > 120 < / span > : unsigned block_state;< / a >
< a name = "121" > < span class = "lineNum" > 121 < / span > : struct snapraid_file* file;< / a >
< a name = "122" > < span class = "lineNum" > 122 < / span > : block_off_t file_pos;< / a >
< a name = "123" > < span class = "lineNum" > 123 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "124" > < span class = "lineNum" > 124 < / span > < span class = "lineCov" > 236664 : block = fs_par2block_find(disk, blockcur);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "125" > < span class = "lineNum" > 125 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "126" > < span class = "lineNum" > 126 < / span > : /* get the state of the block */< / a >
2026-02-28 16:47:55 +01:00
< a name = "127" > < span class = "lineNum" > 127 < / span > < span class = "lineCov" > 236664 : block_state = block_state_get(block);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "128" > < span class = "lineNum" > 128 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "129" > < span class = "lineNum" > 129 < / span > : /* process REP and CHG blocks */< / a >
2026-02-28 16:47:55 +01:00
< a name = "130" > < span class = "lineNum" > 130 < / span > < span class = "lineCov" > 236664 : if (block_state != BLOCK_STATE_REP & & block_state != BLOCK_STATE_CHG)< / span > < / a >
< a name = "131" > < span class = "lineNum" > 131 < / span > < span class = "lineCov" > 223635 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "132" > < span class = "lineNum" > 132 < / span > : < / a >
< a name = "133" > < span class = "lineNum" > 133 < / span > : /* get the file of this block */< / a >
2026-02-28 16:47:55 +01:00
< a name = "134" > < span class = "lineNum" > 134 < / span > < span class = "lineCov" > 13039 : file = fs_par2file_get(disk, blockcur, & file_pos);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "135" > < span class = "lineNum" > 135 < / span > : < / a >
< a name = "136" > < span class = "lineNum" > 136 < / span > : /* get block specific info */< / a >
2026-02-28 16:47:55 +01:00
< a name = "137" > < span class = "lineNum" > 137 < / span > < span class = "lineCov" > 13039 : info = info_get(& state-> infoarr, blockcur);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "138" > < span class = "lineNum" > 138 < / span > : < / a >
< a name = "139" > < span class = "lineNum" > 139 < / span > : /* if we have to use the old hash */< / a >
2026-02-28 16:47:55 +01:00
< a name = "140" > < span class = "lineNum" > 140 < / span > < span class = "lineCov" > 13039 : rehash = info_get_rehash(info);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "141" > < span class = "lineNum" > 141 < / span > : < / a >
< a name = "142" > < span class = "lineNum" > 142 < / span > : /* until now is misc */< / a >
2026-02-28 16:47:55 +01:00
< a name = "143" > < span class = "lineNum" > 143 < / span > < span class = "lineCov" > 13039 : state_usage_misc(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "144" > < span class = "lineNum" > 144 < / span > : < / a >
< a name = "145" > < span class = "lineNum" > 145 < / span > : /* if the file is different than the current one, close it */< / a >
2026-02-28 16:47:55 +01:00
< a name = "146" > < span class = "lineNum" > 146 < / span > < span class = "lineCov" > 13039 : if (handle[j].file != 0 & & handle[j].file != file) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "147" > < span class = "lineNum" > 147 < / span > : /* keep a pointer at the file we are going to close for error reporting */< / a >
2026-02-28 16:47:55 +01:00
< a name = "148" > < span class = "lineNum" > 148 < / span > < span class = "lineCov" > 5252 : struct snapraid_file* report = handle[j].file;< / span > < / a >
< a name = "149" > < span class = "lineNum" > 149 < / span > < span class = "lineCov" > 5252 : ret = handle_close(& handle[j]);< / span > < / a >
< a name = "150" > < span class = "lineNum" > 150 < / span > < span class = "lineCov" > 5252 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "151" > < span class = "lineNum" > 151 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "152" > < span class = "lineNum" > 152 < / span > : /* This one is really an unexpected error, because we are only reading */< / a >
< a name = "153" > < span class = "lineNum" > 153 < / span > : /* and closing a descriptor should never fail */< / a >
< a name = "154" > < span class = "lineNum" > 154 < / span > : log_tag(" %s:%u:%s:%s: Close error. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(report-> sub, esc_buffer), strerror(errno));< / a >
< a name = "155" > < span class = "lineNum" > 155 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "156" > < span class = "lineNum" > 156 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "157" > < span class = "lineNum" > 157 < / span > : < / a >
< a name = "158" > < span class = "lineNum" > 158 < / span > : if (is_hw(errno)) {< / a >
< a name = "159" > < span class = "lineNum" > 159 < / span > : ++io_error;< / a >
< a name = "160" > < span class = "lineNum" > 160 < / span > : } else {< / a >
< a name = "161" > < span class = "lineNum" > 161 < / span > : ++soft_error;< / a >
< a name = "162" > < span class = "lineNum" > 162 < / span > : }< / a >
< a name = "163" > < span class = "lineNum" > 163 < / span > : goto bail;< / a >
< a name = "164" > < span class = "lineNum" > 164 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "165" > < span class = "lineNum" > 165 < / span > : }< / a >
< a name = "166" > < span class = "lineNum" > 166 < / span > : }< / a >
< a name = "167" > < span class = "lineNum" > 167 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "168" > < span class = "lineNum" > 168 < / span > < span class = "lineCov" > 13039 : ret = handle_open(& handle[j], file, state-> file_mode, log_error, log_error); /* output a message for missing files */< / span > < / a >
< a name = "169" > < span class = "lineNum" > 169 < / span > < span class = "lineCov" > 13039 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "170" > < span class = "lineNum" > 170 < / span > < span class = "lineCov" > 6 : log_tag(" %s:%u:%s:%s: Open error. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(file-> sub, esc_buffer), strerror(errno));< / span > < / a >
< a name = "171" > < span class = "lineNum" > 171 < / span > < span class = "lineCov" > 6 : if (errno == ENOENT) {< / span > < / a >
< a name = "172" > < span class = "lineNum" > 172 < / span > < span class = "lineCov" > 2 : log_error_errno(errno, disk-> name);< / span > < / a >
< a name = "173" > < span class = "lineNum" > 173 < / span > : < / a >
< a name = "174" > < span class = "lineNum" > 174 < / span > < span class = "lineCov" > 2 : ++soft_error;< / span > < / a >
< a name = "175" > < span class = "lineNum" > 175 < / span > : /* if the file is missing, it means that it was removed during sync */< / a >
< a name = "176" > < span class = "lineNum" > 176 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "177" > < span class = "lineNum" > 177 < / span > < span class = "lineCov" > 2 : continue;< / span > < / a >
< a name = "178" > < span class = "lineNum" > 178 < / span > : }< / a >
< a name = "179" > < span class = "lineNum" > 179 < / span > : < / a >
< a name = "180" > < span class = "lineNum" > 180 < / span > < span class = "lineCov" > 4 : if (errno == EACCES) {< / span > < / a >
< a name = "181" > < span class = "lineNum" > 181 < / span > < span class = "lineCov" > 4 : log_error_errno(errno, disk-> name);< / span > < / a >
< a name = "182" > < span class = "lineNum" > 182 < / span > : < / a >
< a name = "183" > < span class = "lineNum" > 183 < / span > < span class = "lineCov" > 4 : ++soft_error;< / span > < / a >
< a name = "184" > < span class = "lineNum" > 184 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "185" > < span class = "lineNum" > 185 < / span > < span class = "lineCov" > 4 : continue;< / span > < / a >
< a name = "186" > < span class = "lineNum" > 186 < / span > : }< / a >
< a name = "187" > < span class = "lineNum" > 187 < / span > : < / a >
< a name = "188" > < span class = "lineNum" > 188 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "189" > < span class = "lineNum" > 189 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "190" > < span class = "lineNum" > 190 < / span > : < / a >
< a name = "191" > < span class = "lineNum" > 191 < / span > : if (is_hw(errno)) {< / a >
< a name = "192" > < span class = "lineNum" > 192 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "193" > < span class = "lineNum" > 193 < / span > : ++io_error;< / a >
< a name = "194" > < span class = "lineNum" > 194 < / span > : } else {< / a >
< a name = "195" > < span class = "lineNum" > 195 < / span > : log_fatal(errno, " Stopping to allow recovery. Try with 'snapraid check -f /%s'\n" , fmt_poll(disk, file-> sub, esc_buffer));< / a >
< a name = "196" > < span class = "lineNum" > 196 < / span > : ++soft_error;< / a >
< a name = "197" > < span class = "lineNum" > 197 < / span > : }< / a >
< a name = "198" > < span class = "lineNum" > 198 < / span > : goto bail;< / a >
< a name = "199" > < span class = "lineNum" > 199 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "200" > < span class = "lineNum" > 200 < / span > : }< / a >
< a name = "201" > < span class = "lineNum" > 201 < / span > : < / a >
< a name = "202" > < span class = "lineNum" > 202 < / span > : /* check if the file is changed */< / a >
2026-02-28 16:47:55 +01:00
< a name = "203" > < span class = "lineNum" > 203 < / span > < span class = "lineCov" > 13033 : if (handle[j].st.st_size != file-> size< / span > < / a >
< a name = "204" > < span class = "lineNum" > 204 < / span > < span class = "lineCov" > 13032 : || handle[j].st.st_mtime != file-> mtime_sec< / span > < / a >
< a name = "205" > < span class = "lineNum" > 205 < / span > < span class = "lineCov" > 13031 : || STAT_NSEC(& handle[j].st) != file-> mtime_nsec< / span > < / a >
< a name = "206" > < span class = "lineNum" > 206 < / span > < span class = "lineCov" > 13031 : || handle[j].st.st_ino != file-> inode< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "207" > < span class = "lineNum" > 207 < / span > : ) {< / a >
< a name = "208" > < span class = "lineNum" > 208 < / span > < span class = "lineCov" > 3 : if (handle[j].st.st_size != file-> size) {< / span > < / a >
< a name = "209" > < span class = "lineNum" > 209 < / span > < span class = "lineCov" > 1 : log_tag(" error:%u:%s:%s: Unexpected size change\n" , blockcur, disk-> name, esc_tag(file-> sub, esc_buffer));< / span > < / a >
< a name = "210" > < span class = "lineNum" > 210 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 " .\n" , handle[j].path, file-> size, (uint64_t)handle[j].st.st_size);< / span > < / a >
< a name = "211" > < span class = "lineNum" > 211 < / span > < span class = "lineCov" > 2 : } else if (handle[j].st.st_mtime != file-> mtime_sec< / span > < / a >
< a name = "212" > < span class = "lineNum" > 212 < / span > < span class = "lineCov" > 1 : || STAT_NSEC(& handle[j].st) != file-> mtime_nsec) {< / span > < / a >
< a name = "213" > < span class = "lineNum" > 213 < / span > < span class = "lineCov" > 1 : log_tag(" error:%u:%s:%s: Unexpected time change\n" , blockcur, disk-> name, esc_tag(file-> sub, esc_buffer));< / span > < / a >
< a name = "214" > < span class = "lineNum" > 214 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " Unexpected time change at file '%s' from %" PRIu64 " .%d to %" PRIu64 " .%d.\n" , handle[j].path, file-> mtime_sec, file-> mtime_nsec, (uint64_t)handle[j].st.st_mtime, STAT_NSEC(& handle[j].st));< / span > < / a >
< a name = "215" > < span class = "lineNum" > 215 < / span > : } else {< / a >
< a name = "216" > < span class = "lineNum" > 216 < / span > < span class = "lineCov" > 1 : log_tag(" error:%u:%s:%s: Unexpected inode change\n" , blockcur, disk-> name, esc_tag(file-> sub, esc_buffer));< / span > < / a >
< a name = "217" > < span class = "lineNum" > 217 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " Unexpected inode change from %" PRIu64 " to %" PRIu64 " at file '%s'.\n" , file-> inode, (uint64_t)handle[j].st.st_ino, handle[j].path);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "218" > < span class = "lineNum" > 218 < / span > : }< / a >
2026-02-28 09:59:35 +01:00
< a name = "219" > < span class = "lineNum" > 219 < / span > < span class = "lineCov" > 3 : log_error_errno(ENOENT, disk-> name); /* same message for ENOENT */< / span > < / a >
< a name = "220" > < span class = "lineNum" > 220 < / span > : < / a >
< a name = "221" > < span class = "lineNum" > 221 < / span > < span class = "lineCov" > 3 : ++soft_error;< / span > < / a >
< a name = "222" > < span class = "lineNum" > 222 < / span > : < / a >
< a name = "223" > < span class = "lineNum" > 223 < / span > : /* if the file is changed, it means that it was modified during sync */< / a >
< a name = "224" > < span class = "lineNum" > 224 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "225" > < span class = "lineNum" > 225 < / span > < span class = "lineCov" > 3 : continue;< / span > < / a >
< a name = "226" > < span class = "lineNum" > 226 < / span > : }< / a >
< a name = "227" > < span class = "lineNum" > 227 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "228" > < span class = "lineNum" > 228 < / span > < span class = "lineCov" > 13030 : read_size = handle_read(& handle[j], file_pos, buffer, state-> block_size, log_fatal, 0);< / span > < / a >
< a name = "229" > < span class = "lineNum" > 229 < / span > < span class = "lineCov" > 13030 : if (read_size == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "230" > < span class = "lineNum" > 230 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "231" > < span class = "lineNum" > 231 < / span > : log_tag(" %s:%u:%s:%s: Read error at position %u. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(file-> sub, esc_buffer), file_pos, strerror(errno));< / a >
< a name = "232" > < span class = "lineNum" > 232 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "233" > < span class = "lineNum" > 233 < / span > : < / a >
< a name = "234" > < span class = "lineNum" > 234 < / span > : if (is_hw(errno)) {< / a >
< a name = "235" > < span class = "lineNum" > 235 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "236" > < span class = "lineNum" > 236 < / span > : ++io_error;< / a >
< a name = "237" > < span class = "lineNum" > 237 < / span > : } else {< / a >
< a name = "238" > < span class = "lineNum" > 238 < / span > : log_fatal(errno, " Stopping to allow recovery. Try with 'snapraid check -f /%s'\n" , fmt_poll(disk, file-> sub, esc_buffer));< / a >
< a name = "239" > < span class = "lineNum" > 239 < / span > : ++soft_error;< / a >
< a name = "240" > < span class = "lineNum" > 240 < / span > : }< / a >
< a name = "241" > < span class = "lineNum" > 241 < / span > : goto bail;< / a >
< a name = "242" > < span class = "lineNum" > 242 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "243" > < span class = "lineNum" > 243 < / span > : }< / a >
< a name = "244" > < span class = "lineNum" > 244 < / span > : < / a >
< a name = "245" > < span class = "lineNum" > 245 < / span > : /* until now is disk */< / a >
2026-02-28 16:47:55 +01:00
< a name = "246" > < span class = "lineNum" > 246 < / span > < span class = "lineCov" > 13030 : state_usage_disk(state, handle, & j, 1);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "247" > < span class = "lineNum" > 247 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "248" > < span class = "lineNum" > 248 < / span > < span class = "lineCov" > 13030 : state_usage_file(state, disk, file);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "249" > < span class = "lineNum" > 249 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "250" > < span class = "lineNum" > 250 < / span > < span class = "lineCov" > 13030 : countsize += read_size;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "251" > < span class = "lineNum" > 251 < / span > : < / a >
< a name = "252" > < span class = "lineNum" > 252 < / span > : /* now compute the hash */< / a >
2026-02-28 16:47:55 +01:00
< a name = "253" > < span class = "lineNum" > 253 < / span > < span class = "lineCov" > 13030 : if (rehash) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "254" > < span class = "lineNum" > 254 < / span > < span class = "lineNoCov" > 0 : memhash(state-> prevhash, state-> prevhashseed, hash, buffer, read_size);< / span > < / a >
< a name = "255" > < span class = "lineNum" > 255 < / span > : } else {< / a >
2026-02-28 16:47:55 +01:00
< a name = "256" > < span class = "lineNum" > 256 < / span > < span class = "lineCov" > 13030 : memhash(state-> hash, state-> hashseed, hash, buffer, read_size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "257" > < span class = "lineNum" > 257 < / span > : }< / a >
< a name = "258" > < span class = "lineNum" > 258 < / span > : < / a >
< a name = "259" > < span class = "lineNum" > 259 < / span > : /* until now is hash */< / a >
2026-02-28 16:47:55 +01:00
< a name = "260" > < span class = "lineNum" > 260 < / span > < span class = "lineCov" > 13030 : state_usage_hash(state);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "261" > < span class = "lineNum" > 261 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "262" > < span class = "lineNum" > 262 < / span > < span class = "lineCov" > 13030 : if (block_state == BLOCK_STATE_REP) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "263" > < span class = "lineNum" > 263 < / span > : /* compare the hash */< / a >
2026-02-28 16:47:55 +01:00
< a name = "264" > < span class = "lineNum" > 264 < / span > < span class = "lineCov" > 13028 : if (memcmp(hash, block-> hash, BLOCK_HASH_SIZE) != 0) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "265" > < span class = "lineNum" > 265 < / span > < span class = "lineCov" > 1 : log_tag(" error_data:%u:%s:%s: Unexpected data change\n" , blockcur, disk-> name, esc_tag(file-> sub, esc_buffer));< / span > < / a >
< a name = "266" > < span class = "lineNum" > 266 < / span > < span class = "lineCov" > 1 : log_error(EDATA, " Data change at file '%s' at position '%u'\n" , handle[j].path, file_pos);< / span > < / a >
< a name = "267" > < span class = "lineNum" > 267 < / span > < span class = "lineCov" > 1 : log_error(EDATA, " WARNING! Unexpected data modification of a file without parity!\n" );< / span > < / a >
< a name = "268" > < span class = "lineNum" > 268 < / span > : < / a >
< a name = "269" > < span class = "lineNum" > 269 < / span > < span class = "lineCov" > 1 : if (file_flag_has(file, FILE_IS_COPY)) {< / span > < / a >
< a name = "270" > < span class = "lineNum" > 270 < / span > < span class = "lineCov" > 1 : log_error(EDATA, " This file was detected as a copy of another file with the same name, size,\n" );< / span > < / a >
< a name = "271" > < span class = "lineNum" > 271 < / span > < span class = "lineCov" > 1 : log_error(EDATA, " and timestamp, but the file data isn't matching the assumed copy.\n" );< / span > < / a >
< a name = "272" > < span class = "lineNum" > 272 < / span > < span class = "lineCov" > 1 : log_error(EDATA, " If this is a false positive, and the files are expected to be different,\n" );< / span > < / a >
< a name = "273" > < span class = "lineNum" > 273 < / span > < span class = "lineCov" > 1 : log_error(EDATA, " you can 'sync' anyway using 'snapraid --force-nocopy sync'\n" );< / span > < / a >
< a name = "274" > < span class = "lineNum" > 274 < / span > : } else {< / a >
< a name = "275" > < span class = "lineNum" > 275 < / span > < span class = "lineNoCov" > 0 : log_error(EDATA, " Try removing the file from the array and rerun the 'sync' command!\n" );< / span > < / a >
< a name = "276" > < span class = "lineNum" > 276 < / span > : }< / a >
< a name = "277" > < span class = "lineNum" > 277 < / span > : < / a >
< a name = "278" > < span class = "lineNum" > 278 < / span > : /* block sync to allow a recovery before overwriting */< / a >
< a name = "279" > < span class = "lineNum" > 279 < / span > : /* the parity needed to make such recovery */< / a >
< a name = "280" > < span class = "lineNum" > 280 < / span > < span class = "lineCov" > 1 : *skip_sync = 1; /* avoid to run the next sync */< / span > < / a >
< a name = "281" > < span class = "lineNum" > 281 < / span > : < / a >
< a name = "282" > < span class = "lineNum" > 282 < / span > < span class = "lineCov" > 1 : ++silent_error;< / span > < / a >
< a name = "283" > < span class = "lineNum" > 283 < / span > < span class = "lineCov" > 1 : continue;< / span > < / a >
< a name = "284" > < span class = "lineNum" > 284 < / span > : }< / a >
< a name = "285" > < span class = "lineNum" > 285 < / span > : } else {< / a >
< a name = "286" > < span class = "lineNum" > 286 < / span > : /* the only other case is BLOCK_STATE_CHG */< / a >
< a name = "287" > < span class = "lineNum" > 287 < / span > < span class = "lineCov" > 2 : assert(block_state == BLOCK_STATE_CHG);< / span > < / a >
< a name = "288" > < span class = "lineNum" > 288 < / span > : < / a >
< a name = "289" > < span class = "lineNum" > 289 < / span > : /* copy the hash in the block */< / a >
< a name = "290" > < span class = "lineNum" > 290 < / span > < span class = "lineCov" > 2 : memcpy(block-> hash, hash, BLOCK_HASH_SIZE);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "291" > < span class = "lineNum" > 291 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "292" > < span class = "lineNum" > 292 < / span > : /* and mark the block as hashed */< / a >
< a name = "293" > < span class = "lineNum" > 293 < / span > < span class = "lineCov" > 2 : block_state_set(block, BLOCK_STATE_REP);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "294" > < span class = "lineNum" > 294 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "295" > < span class = "lineNum" > 295 < / span > : /* mark the state as needing write */< / a >
< a name = "296" > < span class = "lineNum" > 296 < / span > < span class = "lineCov" > 2 : state-> need_write = 1;< / span > < / a >
< a name = "297" > < span class = "lineNum" > 297 < / span > : }< / a >
< a name = "298" > < span class = "lineNum" > 298 < / span > : < / a >
< a name = "299" > < span class = "lineNum" > 299 < / span > : /* count the number of processed block */< / a >
2026-02-28 16:47:55 +01:00
< a name = "300" > < span class = "lineNum" > 300 < / span > < span class = "lineCov" > 13029 : ++countpos;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "301" > < span class = "lineNum" > 301 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "302" > < span class = "lineNum" > 302 < / span > : /* progress */< / a >
2026-02-28 16:47:55 +01:00
< a name = "303" > < span class = "lineNum" > 303 < / span > < span class = "lineCov" > 13029 : if (state_progress(state, 0, blockcur, countpos, countmax, countsize)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "304" > < span class = "lineNum" > 304 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "305" > < span class = "lineNum" > 305 < / span > : *skip_sync = 1; /* avoid to run the next sync */< / a >
< a name = "306" > < span class = "lineNum" > 306 < / span > : break;< / a >
< a name = "307" > < span class = "lineNum" > 307 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "308" > < span class = "lineNum" > 308 < / span > : }< / a >
< a name = "309" > < span class = "lineNum" > 309 < / span > : }< / a >
< a name = "310" > < span class = "lineNum" > 310 < / span > : < / a >
< a name = "311" > < span class = "lineNum" > 311 < / span > : /* close the last file in the disk */< / a >
< a name = "312" > < span class = "lineNum" > 312 < / span > < span class = "lineCov" > 42 : if (handle[j].file != 0) {< / span > < / a >
< a name = "313" > < span class = "lineNum" > 313 < / span > : /* keep a pointer at the file we are going to close for error reporting */< / a >
< a name = "314" > < span class = "lineNum" > 314 < / span > < span class = "lineCov" > 7 : struct snapraid_file* report = handle[j].file;< / span > < / a >
< a name = "315" > < span class = "lineNum" > 315 < / span > < span class = "lineCov" > 7 : ret = handle_close(& handle[j]);< / span > < / a >
< a name = "316" > < span class = "lineNum" > 316 < / span > < span class = "lineCov" > 7 : if (ret == -1) {< / span > < / a >
< a name = "317" > < span class = "lineNum" > 317 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "318" > < span class = "lineNum" > 318 < / span > : /* This one is really an unexpected error, because we are only reading */< / a >
< a name = "319" > < span class = "lineNum" > 319 < / span > : /* and closing a descriptor should never fail */< / a >
< a name = "320" > < span class = "lineNum" > 320 < / span > : log_tag(" %s:%u:%s:%s: Close error. %s.\n" , es(errno), blockmax, disk-> name, esc_tag(report-> sub, esc_buffer), strerror(errno));< / a >
< a name = "321" > < span class = "lineNum" > 321 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "322" > < span class = "lineNum" > 322 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockmax);< / a >
< a name = "323" > < span class = "lineNum" > 323 < / span > : < / a >
< a name = "324" > < span class = "lineNum" > 324 < / span > : if (is_hw(errno)) {< / a >
< a name = "325" > < span class = "lineNum" > 325 < / span > : ++io_error;< / a >
< a name = "326" > < span class = "lineNum" > 326 < / span > : } else {< / a >
< a name = "327" > < span class = "lineNum" > 327 < / span > : ++soft_error;< / a >
< a name = "328" > < span class = "lineNum" > 328 < / span > : }< / a >
< a name = "329" > < span class = "lineNum" > 329 < / span > : goto bail;< / a >
< a name = "330" > < span class = "lineNum" > 330 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "331" > < span class = "lineNum" > 331 < / span > : }< / a >
< a name = "332" > < span class = "lineNum" > 332 < / span > : }< / a >
< a name = "333" > < span class = "lineNum" > 333 < / span > : }< / a >
< a name = "334" > < span class = "lineNum" > 334 < / span > : < / a >
< a name = "335" > < span class = "lineNum" > 335 < / span > < span class = "lineCov" > 7 : end:< / span > < / a >
< a name = "336" > < span class = "lineNum" > 336 < / span > < span class = "lineCov" > 7 : state_progress_end(state, countpos, countmax, countsize, " Nothing to hash.\n" );< / span > < / a >
< a name = "337" > < span class = "lineNum" > 337 < / span > : < / a >
< a name = "338" > < span class = "lineNum" > 338 < / span > : /* note that at this point no io_error is possible */< / a >
< a name = "339" > < span class = "lineNum" > 339 < / span > : /* because at the first one we bail out */< / a >
< a name = "340" > < span class = "lineNum" > 340 < / span > < span class = "lineCov" > 7 : assert(io_error == 0);< / span > < / a >
< a name = "341" > < span class = "lineNum" > 341 < / span > : < / a >
< a name = "342" > < span class = "lineNum" > 342 < / span > < span class = "lineCov" > 7 : if (soft_error || io_error || silent_error) {< / span > < / a >
< a name = "343" > < span class = "lineNum" > 343 < / span > < span class = "lineCov" > 6 : msg_status(" \n" );< / span > < / a >
< a name = "344" > < span class = "lineNum" > 344 < / span > < span class = "lineCov" > 6 : msg_status(" %8u soft errors\n" , soft_error);< / span > < / a >
< a name = "345" > < span class = "lineNum" > 345 < / span > < span class = "lineCov" > 6 : msg_status(" %8u io errors\n" , io_error);< / span > < / a >
< a name = "346" > < span class = "lineNum" > 346 < / span > < span class = "lineCov" > 6 : msg_status(" %8u data errors\n" , silent_error);< / span > < / a >
< a name = "347" > < span class = "lineNum" > 347 < / span > : } else {< / a >
< a name = "348" > < span class = "lineNum" > 348 < / span > < span class = "lineCov" > 1 : msg_status(" Everything OK\n" );< / span > < / a >
< a name = "349" > < span class = "lineNum" > 349 < / span > : }< / a >
< a name = "350" > < span class = "lineNum" > 350 < / span > : < / a >
< a name = "351" > < span class = "lineNum" > 351 < / span > < span class = "lineCov" > 7 : if (soft_error)< / span > < / a >
< a name = "352" > < span class = "lineNum" > 352 < / span > < span class = "lineCov" > 5 : log_fatal(ESOFT, " WARNING! Unexpected soft errors!\n" );< / span > < / a >
< a name = "353" > < span class = "lineNum" > 353 < / span > : < / a >
< a name = "354" > < span class = "lineNum" > 354 < / span > < span class = "lineCov" > 7 : log_tag(" hash_summary:error_soft:%u\n" , soft_error);< / span > < / a >
< a name = "355" > < span class = "lineNum" > 355 < / span > : < / a >
< a name = "356" > < span class = "lineNum" > 356 < / span > : /* proceed without bailing out */< / a >
< a name = "357" > < span class = "lineNum" > 357 < / span > < span class = "lineCov" > 7 : goto finish;< / span > < / a >
< a name = "358" > < span class = "lineNum" > 358 < / span > : < / a >
< a name = "359" > < span class = "lineNum" > 359 < / span > < span class = "lineNoCov" > 0 : bail:< / span > < / a >
< a name = "360" > < span class = "lineNum" > 360 < / span > : /* on bail, don't run the next sync */< / a >
< a name = "361" > < span class = "lineNum" > 361 < / span > < span class = "lineNoCov" > 0 : *skip_sync = 1;< / span > < / a >
< a name = "362" > < span class = "lineNum" > 362 < / span > : < / a >
< a name = "363" > < span class = "lineNum" > 363 < / span > : /* close files left open */< / a >
< a name = "364" > < span class = "lineNum" > 364 < / span > < span class = "lineNoCov" > 0 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
< a name = "365" > < span class = "lineNum" > 365 < / span > < span class = "lineNoCov" > 0 : struct snapraid_file* file = handle[j].file;< / span > < / a >
< a name = "366" > < span class = "lineNum" > 366 < / span > < span class = "lineNoCov" > 0 : struct snapraid_disk* disk = handle[j].disk;< / span > < / a >
< a name = "367" > < span class = "lineNum" > 367 < / span > < span class = "lineNoCov" > 0 : ret = handle_close(& handle[j]);< / span > < / a >
< a name = "368" > < span class = "lineNum" > 368 < / span > < span class = "lineNoCov" > 0 : if (ret == -1) {< / span > < / a >
< a name = "369" > < span class = "lineNum" > 369 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "370" > < span class = "lineNum" > 370 < / span > : log_tag(" %s:%u:%s:%s: Close error. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(file-> sub, esc_buffer), strerror(errno));< / a >
< a name = "371" > < span class = "lineNum" > 371 < / span > : log_fatal_errno(errno, disk-> name);< / a >
2025-10-28 12:01:21 +01:00
< a name = "372" > < span class = "lineNum" > 372 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "373" > < span class = "lineNum" > 373 < / span > : if (is_hw(errno)) {< / a >
< a name = "374" > < span class = "lineNum" > 374 < / span > : ++io_error;< / a >
< a name = "375" > < span class = "lineNum" > 375 < / span > : } else {< / a >
< a name = "376" > < span class = "lineNum" > 376 < / span > : ++soft_error;< / a >
< a name = "377" > < span class = "lineNum" > 377 < / span > : }< / a >
< a name = "378" > < span class = "lineNum" > 378 < / span > : /* continue, as we are already exiting */< / a >
< a name = "379" > < span class = "lineNum" > 379 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "380" > < span class = "lineNum" > 380 < / span > : }< / a >
< a name = "381" > < span class = "lineNum" > 381 < / span > : }< / a >
< a name = "382" > < span class = "lineNum" > 382 < / span > : < / a >
< a name = "383" > < span class = "lineNum" > 383 < / span > < span class = "lineNoCov" > 0 : finish:< / span > < / a >
< a name = "384" > < span class = "lineNum" > 384 < / span > < span class = "lineCov" > 7 : free(handle);< / span > < / a >
< a name = "385" > < span class = "lineNum" > 385 < / span > < span class = "lineCov" > 7 : free(buffer_alloc);< / span > < / a >
< a name = "386" > < span class = "lineNum" > 386 < / span > : < / a >
< a name = "387" > < span class = "lineNum" > 387 < / span > < span class = "lineCov" > 7 : if (soft_error + io_error + silent_error != 0)< / span > < / a >
< a name = "388" > < span class = "lineNum" > 388 < / span > < span class = "lineCov" > 6 : return -1;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "389" > < span class = "lineNum" > 389 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "390" > < span class = "lineNum" > 390 < / span > < span class = "lineCov" > 1 : if (alert < 0)< / span > < / a >
< a name = "391" > < span class = "lineNum" > 391 < / span > < span class = "lineNoCov" > 0 : return -1;< / span > < / a >
< a name = "392" > < span class = "lineNum" > 392 < / span > : < / a >
< a name = "393" > < span class = "lineNum" > 393 < / span > < span class = "lineCov" > 1 : return 0;< / span > < / a >
< a name = "394" > < span class = "lineNum" > 394 < / span > : }< / a >
< a name = "395" > < span class = "lineNum" > 395 < / span > : < / a >
< a name = "396" > < span class = "lineNum" > 396 < / span > : /****************************************************************************/< / a >
< a name = "397" > < span class = "lineNum" > 397 < / span > : /* sync */< / a >
< a name = "398" > < span class = "lineNum" > 398 < / span > : < / a >
< a name = "399" > < span class = "lineNum" > 399 < / span > : /**< / a >
< a name = "400" > < span class = "lineNum" > 400 < / span > : * Sync plan to use.< / a >
< a name = "401" > < span class = "lineNum" > 401 < / span > : */< / a >
< a name = "402" > < span class = "lineNum" > 402 < / span > : struct snapraid_plan {< / a >
< a name = "403" > < span class = "lineNum" > 403 < / span > : unsigned handle_max;< / a >
< a name = "404" > < span class = "lineNum" > 404 < / span > : struct snapraid_handle* handle_map;< / a >
< a name = "405" > < span class = "lineNum" > 405 < / span > : int force_full;< / a >
< a name = "406" > < span class = "lineNum" > 406 < / span > : };< / a >
< a name = "407" > < span class = "lineNum" > 407 < / span > : < / a >
< a name = "408" > < span class = "lineNum" > 408 < / span > : /**< / a >
< a name = "409" > < span class = "lineNum" > 409 < / span > : * A block that failed the hash check, or that was deleted.< / a >
< a name = "410" > < span class = "lineNum" > 410 < / span > : */< / a >
< a name = "411" > < span class = "lineNum" > 411 < / span > : struct failed_struct {< / a >
< a name = "412" > < span class = "lineNum" > 412 < / span > : unsigned index; /**< Index of the failed block. */< / a >
< a name = "413" > < span class = "lineNum" > 413 < / span > : unsigned size; /**< Size of the block. */< / a >
< a name = "414" > < span class = "lineNum" > 414 < / span > : < / a >
< a name = "415" > < span class = "lineNum" > 415 < / span > : struct snapraid_block* block; /**< The failed block, or BLOCK_DELETED for a deleted block */< / a >
< a name = "416" > < span class = "lineNum" > 416 < / span > : };< / a >
< a name = "417" > < span class = "lineNum" > 417 < / span > : < / a >
< a name = "418" > < span class = "lineNum" > 418 < / span > : /**< / a >
< a name = "419" > < span class = "lineNum" > 419 < / span > : * Comparison function for sorting by index.< / a >
< a name = "420" > < span class = "lineNum" > 420 < / span > : */< / a >
2026-02-28 10:26:32 +01:00
< a name = "421" > < span class = "lineNum" > 421 < / span > < span class = "lineCov" > 852 : int failed_compare_by_index(const void* void_a, const void* void_b)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "422" > < span class = "lineNum" > 422 < / span > : {< / a >
2026-02-28 10:26:32 +01:00
< a name = "423" > < span class = "lineNum" > 423 < / span > < span class = "lineCov" > 852 : const struct failed_struct* a = void_a;< / span > < / a >
< a name = "424" > < span class = "lineNum" > 424 < / span > < span class = "lineCov" > 852 : const struct failed_struct* b = void_b;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "425" > < span class = "lineNum" > 425 < / span > : < / a >
2026-02-28 10:26:32 +01:00
< a name = "426" > < span class = "lineNum" > 426 < / span > < span class = "lineCov" > 852 : if (a-> index < b-> index)< / span > < / a >
< a name = "427" > < span class = "lineNum" > 427 < / span > < span class = "lineCov" > 852 : return -1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "428" > < span class = "lineNum" > 428 < / span > < span class = "lineNoCov" > 0 : if (a-> index > b-> index)< / span > < / a >
< a name = "429" > < span class = "lineNum" > 429 < / span > < span class = "lineNoCov" > 0 : return 1;< / span > < / a >
< a name = "430" > < span class = "lineNum" > 430 < / span > < span class = "lineNoCov" > 0 : return 0;< / span > < / a >
< a name = "431" > < span class = "lineNum" > 431 < / span > : }< / a >
< a name = "432" > < span class = "lineNum" > 432 < / span > : < / a >
< a name = "433" > < span class = "lineNum" > 433 < / span > : /**< / a >
< a name = "434" > < span class = "lineNum" > 434 < / span > : * Buffer for storing the new hashes.< / a >
< a name = "435" > < span class = "lineNum" > 435 < / span > : */< / a >
< a name = "436" > < span class = "lineNum" > 436 < / span > : struct snapraid_rehash {< / a >
< a name = "437" > < span class = "lineNum" > 437 < / span > : unsigned char hash[HASH_MAX];< / a >
< a name = "438" > < span class = "lineNum" > 438 < / span > : struct snapraid_block* block;< / a >
< a name = "439" > < span class = "lineNum" > 439 < / span > : };< / a >
< a name = "440" > < span class = "lineNum" > 440 < / span > : < / a >
< a name = "441" > < span class = "lineNum" > 441 < / span > : /**< / a >
< a name = "442" > < span class = "lineNum" > 442 < / span > : * Check if we have to process the specified block index ::i.< / a >
< a name = "443" > < span class = "lineNum" > 443 < / span > : */< / a >
2026-02-28 16:47:55 +01:00
< a name = "444" > < span class = "lineNum" > 444 < / span > < span class = "lineCov" > 463114 : static int block_is_enabled(struct snapraid_plan* plan, block_off_t i)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "445" > < span class = "lineNum" > 445 < / span > : {< / a >
< a name = "446" > < span class = "lineNum" > 446 < / span > : unsigned j;< / a >
< a name = "447" > < span class = "lineNum" > 447 < / span > : int one_invalid;< / a >
< a name = "448" > < span class = "lineNum" > 448 < / span > : int one_valid;< / a >
< a name = "449" > < span class = "lineNum" > 449 < / span > : < / a >
< a name = "450" > < span class = "lineNum" > 450 < / span > : /* for each disk */< / a >
2026-02-28 16:47:55 +01:00
< a name = "451" > < span class = "lineNum" > 451 < / span > < span class = "lineCov" > 463114 : one_invalid = 0;< / span > < / a >
< a name = "452" > < span class = "lineNum" > 452 < / span > < span class = "lineCov" > 463114 : one_valid = 0;< / span > < / a >
< a name = "453" > < span class = "lineNum" > 453 < / span > < span class = "lineCov" > 3241798 : for (j = 0; j < plan-> handle_max; ++j) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "454" > < span class = "lineNum" > 454 < / span > : struct snapraid_block* block;< / a >
2026-02-28 16:47:55 +01:00
< a name = "455" > < span class = "lineNum" > 455 < / span > < span class = "lineCov" > 2778684 : struct snapraid_disk* disk = plan-> handle_map[j].disk;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "456" > < span class = "lineNum" > 456 < / span > : < / a >
< a name = "457" > < span class = "lineNum" > 457 < / span > : /* if no disk, nothing to check */< / a >
2026-02-28 16:47:55 +01:00
< a name = "458" > < span class = "lineNum" > 458 < / span > < span class = "lineCov" > 2778684 : if (!disk)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "459" > < span class = "lineNum" > 459 < / span > < span class = "lineCov" > 4687 : continue;< / span > < / a >
< a name = "460" > < span class = "lineNum" > 460 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "461" > < span class = "lineNum" > 461 < / span > < span class = "lineCov" > 2773997 : block = fs_par2block_find(disk, i);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "462" > < span class = "lineNum" > 462 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "463" > < span class = "lineNum" > 463 < / span > < span class = "lineCov" > 2773997 : if (block_has_file(block))< / span > < / a >
< a name = "464" > < span class = "lineNum" > 464 < / span > < span class = "lineCov" > 2623692 : one_valid = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "465" > < span class = "lineNum" > 465 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "466" > < span class = "lineNum" > 466 < / span > < span class = "lineCov" > 2773997 : if (block_has_invalid_parity(block) || plan-> force_full)< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "467" > < span class = "lineNum" > 467 < / span > < span class = "lineCov" > 434554 : one_invalid = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "468" > < span class = "lineNum" > 468 < / span > : }< / a >
< a name = "469" > < span class = "lineNum" > 469 < / span > : < / a >
< a name = "470" > < span class = "lineNum" > 470 < / span > : /* if none valid or none invalid, we don't need to update */< / a >
2026-02-28 16:47:55 +01:00
< a name = "471" > < span class = "lineNum" > 471 < / span > < span class = "lineCov" > 463114 : if (!one_invalid || !one_valid)< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "472" > < span class = "lineNum" > 472 < / span > < span class = "lineCov" > 337042 : return 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "473" > < span class = "lineNum" > 473 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "474" > < span class = "lineNum" > 474 < / span > < span class = "lineCov" > 126072 : return 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "475" > < span class = "lineNum" > 475 < / span > : }< / a >
< a name = "476" > < span class = "lineNum" > 476 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "477" > < span class = "lineNum" > 477 < / span > < span class = "lineCov" > 756432 : static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "478" > < span class = "lineNum" > 478 < / span > : {< / a >
2026-03-15 18:52:43 +01:00
< a name = "479" > < span class = "lineNum" > 479 < / span > < span class = "lineCov" > 756432 : struct snapraid_io* io = worker-> io;< / span > < / a >
< a name = "480" > < span class = "lineNum" > 480 < / span > < span class = "lineCov" > 756432 : struct snapraid_state* state = io-> state;< / span > < / a >
< a name = "481" > < span class = "lineNum" > 481 < / span > < span class = "lineCov" > 756432 : struct snapraid_handle* handle = worker-> handle;< / span > < / a >
< a name = "482" > < span class = "lineNum" > 482 < / span > < span class = "lineCov" > 756432 : struct snapraid_disk* disk = handle-> disk;< / span > < / a >
< a name = "483" > < span class = "lineNum" > 483 < / span > < span class = "lineCov" > 756432 : block_off_t blockcur = task-> position;< / span > < / a >
< a name = "484" > < span class = "lineNum" > 484 < / span > < span class = "lineCov" > 756432 : unsigned char* buffer = task-> buffer;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "485" > < span class = "lineNum" > 485 < / span > : int ret;< / a >
< a name = "486" > < span class = "lineNum" > 486 < / span > : char esc_buffer[ESC_MAX];< / a >
< a name = "487" > < span class = "lineNum" > 487 < / span > : < / a >
< a name = "488" > < span class = "lineNum" > 488 < / span > : /* if the disk position is not used */< / a >
2026-03-15 18:52:43 +01:00
< a name = "489" > < span class = "lineNum" > 489 < / span > < span class = "lineCov" > 756432 : if (!disk) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "490" > < span class = "lineNum" > 490 < / span > : /* use an empty block */< / a >
< a name = "491" > < span class = "lineNum" > 491 < / span > < span class = "lineNoCov" > 0 : memset(buffer, 0, state-> block_size);< / span > < / a >
< a name = "492" > < span class = "lineNum" > 492 < / span > < span class = "lineNoCov" > 0 : task-> state = TASK_STATE_DONE;< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "493" > < span class = "lineNum" > 493 < / span > < span class = "lineCov" > 110636 : return;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "494" > < span class = "lineNum" > 494 < / span > : }< / a >
< a name = "495" > < span class = "lineNum" > 495 < / span > : < / a >
< a name = "496" > < span class = "lineNum" > 496 < / span > : /* get the block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "497" > < span class = "lineNum" > 497 < / span > < span class = "lineCov" > 756432 : task-> block = fs_par2block_find(disk, blockcur);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "498" > < span class = "lineNum" > 498 < / span > : < / a >
< a name = "499" > < span class = "lineNum" > 499 < / span > : /* if the block has no file, meaning that it's EMPTY or DELETED, */< / a >
< a name = "500" > < span class = "lineNum" > 500 < / span > : /* it doesn't participate in the new parity computation */< / a >
2026-03-15 18:52:43 +01:00
< a name = "501" > < span class = "lineNum" > 501 < / span > < span class = "lineCov" > 756432 : if (!block_has_file(task-> block)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "502" > < span class = "lineNum" > 502 < / span > : /* use an empty block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "503" > < span class = "lineNum" > 503 < / span > < span class = "lineCov" > 110618 : memset(buffer, 0, state-> block_size);< / span > < / a >
< a name = "504" > < span class = "lineNum" > 504 < / span > < span class = "lineCov" > 110618 : task-> state = TASK_STATE_DONE;< / span > < / a >
< a name = "505" > < span class = "lineNum" > 505 < / span > < span class = "lineCov" > 110618 : return;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "506" > < span class = "lineNum" > 506 < / span > : }< / a >
< a name = "507" > < span class = "lineNum" > 507 < / span > : < / a >
< a name = "508" > < span class = "lineNum" > 508 < / span > : /* get the file of this block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "509" > < span class = "lineNum" > 509 < / span > < span class = "lineCov" > 645814 : task-> file = fs_par2file_get(disk, blockcur, & task-> file_pos);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "510" > < span class = "lineNum" > 510 < / span > : < / a >
< a name = "511" > < span class = "lineNum" > 511 < / span > : /* if the file is different than the current one, close it */< / a >
2026-03-15 18:52:43 +01:00
< a name = "512" > < span class = "lineNum" > 512 < / span > < span class = "lineCov" > 645814 : if (handle-> file != 0 & & handle-> file != task-> file) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "513" > < span class = "lineNum" > 513 < / span > : /* keep a pointer at the file we are going to close for error reporting */< / a >
2026-03-15 18:52:43 +01:00
< a name = "514" > < span class = "lineNum" > 514 < / span > < span class = "lineCov" > 264963 : struct snapraid_file* report = handle-> file;< / span > < / a >
< a name = "515" > < span class = "lineNum" > 515 < / span > < span class = "lineCov" > 264963 : ret = handle_close(handle);< / span > < / a >
< a name = "516" > < span class = "lineNum" > 516 < / span > < span class = "lineCov" > 264963 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "517" > < span class = "lineNum" > 517 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "518" > < span class = "lineNum" > 518 < / span > : /* This one is really an unexpected error, because we are only reading */< / a >
< a name = "519" > < span class = "lineNum" > 519 < / span > : /* and closing a descriptor should never fail */< / a >
< a name = "520" > < span class = "lineNum" > 520 < / span > : log_tag(" %s:%u:%s:%s: Close error. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(report-> sub, esc_buffer), strerror(errno));< / a >
< a name = "521" > < span class = "lineNum" > 521 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "522" > < span class = "lineNum" > 522 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "523" > < span class = "lineNum" > 523 < / span > : < / a >
< a name = "524" > < span class = "lineNum" > 524 < / span > : if (is_hw(errno)) {< / a >
< a name = "525" > < span class = "lineNum" > 525 < / span > : task-> state = TASK_STATE_IOERROR;< / a >
< a name = "526" > < span class = "lineNum" > 526 < / span > : } else {< / a >
< a name = "527" > < span class = "lineNum" > 527 < / span > : task-> state = TASK_STATE_ERROR;< / a >
< a name = "528" > < span class = "lineNum" > 528 < / span > : }< / a >
< a name = "529" > < span class = "lineNum" > 529 < / span > : return;< / a >
< a name = "530" > < span class = "lineNum" > 530 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "531" > < span class = "lineNum" > 531 < / span > : }< / a >
< a name = "532" > < span class = "lineNum" > 532 < / span > : }< / a >
< a name = "533" > < span class = "lineNum" > 533 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "534" > < span class = "lineNum" > 534 < / span > < span class = "lineCov" > 645814 : ret = handle_open(handle, task-> file, state-> file_mode, log_error, log_error); /* output a message for missing files */< / span > < / a >
< a name = "535" > < span class = "lineNum" > 535 < / span > < span class = "lineCov" > 645814 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "536" > < span class = "lineNum" > 536 < / span > < span class = "lineCov" > 12 : log_tag(" %s:%u:%s:%s: Open error. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(task-> file-> sub, esc_buffer), strerror(errno));< / span > < / a >
< a name = "537" > < span class = "lineNum" > 537 < / span > < span class = "lineCov" > 12 : if (errno == ENOENT) {< / span > < / a >
< a name = "538" > < span class = "lineNum" > 538 < / span > < span class = "lineCov" > 4 : log_error_errno(errno, disk-> name);< / span > < / a >
< a name = "539" > < span class = "lineNum" > 539 < / span > : < / a >
< a name = "540" > < span class = "lineNum" > 540 < / span > : /* if the file is missing, it means that it was removed during sync */< / a >
< a name = "541" > < span class = "lineNum" > 541 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "542" > < span class = "lineNum" > 542 < / span > < span class = "lineCov" > 4 : task-> state = TASK_STATE_ERROR_CONTINUE;< / span > < / a >
< a name = "543" > < span class = "lineNum" > 543 < / span > < span class = "lineCov" > 4 : return;< / span > < / a >
< a name = "544" > < span class = "lineNum" > 544 < / span > : }< / a >
< a name = "545" > < span class = "lineNum" > 545 < / span > : < / a >
< a name = "546" > < span class = "lineNum" > 546 < / span > < span class = "lineCov" > 8 : if (errno == EACCES) {< / span > < / a >
< a name = "547" > < span class = "lineNum" > 547 < / span > < span class = "lineCov" > 8 : log_error_errno(errno, disk-> name);< / span > < / a >
< a name = "548" > < span class = "lineNum" > 548 < / span > : < / a >
< a name = "549" > < span class = "lineNum" > 549 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "550" > < span class = "lineNum" > 550 < / span > < span class = "lineCov" > 8 : task-> state = TASK_STATE_ERROR_CONTINUE;< / span > < / a >
< a name = "551" > < span class = "lineNum" > 551 < / span > < span class = "lineCov" > 8 : return;< / span > < / a >
< a name = "552" > < span class = "lineNum" > 552 < / span > : }< / a >
< a name = "553" > < span class = "lineNum" > 553 < / span > : < / a >
< a name = "554" > < span class = "lineNum" > 554 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "555" > < span class = "lineNum" > 555 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "556" > < span class = "lineNum" > 556 < / span > : < / a >
< a name = "557" > < span class = "lineNum" > 557 < / span > : if (is_hw(errno)) {< / a >
< a name = "558" > < span class = "lineNum" > 558 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "559" > < span class = "lineNum" > 559 < / span > : task-> state = TASK_STATE_IOERROR;< / a >
< a name = "560" > < span class = "lineNum" > 560 < / span > : } else {< / a >
< a name = "561" > < span class = "lineNum" > 561 < / span > : log_fatal(errno, " Stopping to allow recovery. Try with 'snapraid check -f /%s'\n" , fmt_poll(disk, task-> file-> sub, esc_buffer));< / a >
< a name = "562" > < span class = "lineNum" > 562 < / span > : task-> state = TASK_STATE_ERROR;< / a >
< a name = "563" > < span class = "lineNum" > 563 < / span > : }< / a >
< a name = "564" > < span class = "lineNum" > 564 < / span > : return;< / a >
< a name = "565" > < span class = "lineNum" > 565 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "566" > < span class = "lineNum" > 566 < / span > : }< / a >
< a name = "567" > < span class = "lineNum" > 567 < / span > : < / a >
< a name = "568" > < span class = "lineNum" > 568 < / span > : /* check if the file is changed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "569" > < span class = "lineNum" > 569 < / span > < span class = "lineCov" > 645802 : if (handle-> st.st_size != task-> file-> size< / span > < / a >
< a name = "570" > < span class = "lineNum" > 570 < / span > < span class = "lineCov" > 645800 : || handle-> st.st_mtime != task-> file-> mtime_sec< / span > < / a >
< a name = "571" > < span class = "lineNum" > 571 < / span > < span class = "lineCov" > 645798 : || STAT_NSEC(& handle-> st) != task-> file-> mtime_nsec< / span > < / a >
< a name = "572" > < span class = "lineNum" > 572 < / span > < span class = "lineCov" > 645798 : || handle-> st.st_ino != task-> file-> inode< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "573" > < span class = "lineNum" > 573 < / span > : ) {< / a >
< a name = "574" > < span class = "lineNum" > 574 < / span > < span class = "lineCov" > 6 : log_tag(" error:%u:%s:%s: Unexpected attribute change\n" , blockcur, disk-> name, esc_tag(task-> file-> sub, esc_buffer));< / span > < / a >
< a name = "575" > < span class = "lineNum" > 575 < / span > < span class = "lineCov" > 6 : if (handle-> st.st_size != task-> file-> size) {< / span > < / a >
< a name = "576" > < span class = "lineNum" > 576 < / span > < span class = "lineCov" > 2 : log_error(ESOFT, " Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 " .\n" , handle-> path, task-> file-> size, (uint64_t)handle-> st.st_size);< / span > < / a >
< a name = "577" > < span class = "lineNum" > 577 < / span > < span class = "lineCov" > 4 : } else if (handle-> st.st_mtime != task-> file-> mtime_sec< / span > < / a >
< a name = "578" > < span class = "lineNum" > 578 < / span > < span class = "lineCov" > 2 : || STAT_NSEC(& handle-> st) != task-> file-> mtime_nsec) {< / span > < / a >
< a name = "579" > < span class = "lineNum" > 579 < / span > < span class = "lineCov" > 2 : log_error(ESOFT, " Unexpected time change at file '%s' from %" PRIu64 " .%d to %" PRIu64 " .%d.\n" , handle-> path, task-> file-> mtime_sec, task-> file-> mtime_nsec, (uint64_t)handle-> st.st_mtime, STAT_NSEC(& handle-> st));< / span > < / a >
< a name = "580" > < span class = "lineNum" > 580 < / span > : } else {< / a >
< a name = "581" > < span class = "lineNum" > 581 < / span > < span class = "lineCov" > 2 : log_error(ESOFT, " Unexpected inode change from %" PRIu64 " to %" PRIu64 " at file '%s'.\n" , task-> file-> inode, (uint64_t)handle-> st.st_ino, handle-> path);< / span > < / a >
< a name = "582" > < span class = "lineNum" > 582 < / span > : }< / a >
< a name = "583" > < span class = "lineNum" > 583 < / span > < span class = "lineCov" > 6 : log_error_errno(ENOENT, disk-> name); /* same message for ENOENT */< / span > < / a >
< a name = "584" > < span class = "lineNum" > 584 < / span > : < / a >
< a name = "585" > < span class = "lineNum" > 585 < / span > : /* if the file is changed, it means that it was modified during sync */< / a >
< a name = "586" > < span class = "lineNum" > 586 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "587" > < span class = "lineNum" > 587 < / span > < span class = "lineCov" > 6 : task-> state = TASK_STATE_ERROR_CONTINUE;< / span > < / a >
< a name = "588" > < span class = "lineNum" > 588 < / span > < span class = "lineCov" > 6 : return;< / span > < / a >
< a name = "589" > < span class = "lineNum" > 589 < / span > : }< / a >
< a name = "590" > < span class = "lineNum" > 590 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "591" > < span class = "lineNum" > 591 < / span > < span class = "lineCov" > 645796 : task-> read_size = handle_read(handle, task-> file_pos, buffer, state-> block_size, log_error, 0);< / span > < / a >
< a name = "592" > < span class = "lineNum" > 592 < / span > < span class = "lineCov" > 645796 : if (task-> read_size == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "593" > < span class = "lineNum" > 593 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "594" > < span class = "lineNum" > 594 < / span > : log_tag(" %s:%u:%s:%s: Read error at position %u. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(task-> file-> sub, esc_buffer), task-> file_pos, strerror(errno));< / a >
< a name = "595" > < span class = "lineNum" > 595 < / span > : < / a >
< a name = "596" > < span class = "lineNum" > 596 < / span > : if (is_hw(errno)) {< / a >
< a name = "597" > < span class = "lineNum" > 597 < / span > : log_error_errno(errno, disk-> name);< / a >
< a name = "598" > < span class = "lineNum" > 598 < / span > : /* continue until the error limit is reached */< / a >
< a name = "599" > < span class = "lineNum" > 599 < / span > : task-> state = TASK_STATE_IOERROR_CONTINUE;< / a >
< a name = "600" > < span class = "lineNum" > 600 < / span > : } else {< / a >
< a name = "601" > < span class = "lineNum" > 601 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "602" > < span class = "lineNum" > 602 < / span > : log_fatal(errno, " Stopping to allow recovery. Try with 'snapraid check -f /%s'\n" , fmt_poll(disk, task-> file-> sub, esc_buffer));< / a >
< a name = "603" > < span class = "lineNum" > 603 < / span > : task-> state = TASK_STATE_ERROR;< / a >
< a name = "604" > < span class = "lineNum" > 604 < / span > : }< / a >
< a name = "605" > < span class = "lineNum" > 605 < / span > : return;< / a >
< a name = "606" > < span class = "lineNum" > 606 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "607" > < span class = "lineNum" > 607 < / span > : }< / a >
< a name = "608" > < span class = "lineNum" > 608 < / span > : < / a >
< a name = "609" > < span class = "lineNum" > 609 < / span > : /* store the path of the opened file */< / a >
2026-03-15 18:52:43 +01:00
< a name = "610" > < span class = "lineNum" > 610 < / span > < span class = "lineCov" > 645796 : pathcpy(task-> path, sizeof(task-> path), handle-> path);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "611" > < span class = "lineNum" > 611 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "612" > < span class = "lineNum" > 612 < / span > < span class = "lineCov" > 645796 : task-> state = TASK_STATE_DONE;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "613" > < span class = "lineNum" > 613 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "614" > < span class = "lineNum" > 614 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "615" > < span class = "lineNum" > 615 < / span > < span class = "lineCov" > 573582 : static void sync_parity_writer(struct snapraid_worker* worker, struct snapraid_task* task)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "616" > < span class = "lineNum" > 616 < / span > : {< / a >
2026-03-15 18:52:43 +01:00
< a name = "617" > < span class = "lineNum" > 617 < / span > < span class = "lineCov" > 573582 : struct snapraid_io* io = worker-> io;< / span > < / a >
< a name = "618" > < span class = "lineNum" > 618 < / span > < span class = "lineCov" > 573582 : struct snapraid_state* state = io-> state;< / span > < / a >
< a name = "619" > < span class = "lineNum" > 619 < / span > < span class = "lineCov" > 573582 : struct snapraid_parity_handle* parity_handle = worker-> parity_handle;< / span > < / a >
< a name = "620" > < span class = "lineNum" > 620 < / span > < span class = "lineCov" > 573582 : unsigned level = parity_handle-> level;< / span > < / a >
< a name = "621" > < span class = "lineNum" > 621 < / span > < span class = "lineCov" > 573582 : block_off_t blockcur = task-> position;< / span > < / a >
< a name = "622" > < span class = "lineNum" > 622 < / span > < span class = "lineCov" > 573582 : unsigned char* buffer = task-> buffer;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "623" > < span class = "lineNum" > 623 < / span > : int ret;< / a >
< a name = "624" > < span class = "lineNum" > 624 < / span > : < / a >
< a name = "625" > < span class = "lineNum" > 625 < / span > : /* write parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "626" > < span class = "lineNum" > 626 < / span > < span class = "lineCov" > 573582 : ret = parity_write(parity_handle, blockcur, buffer, state-> block_size);< / span > < / a >
< a name = "627" > < span class = "lineNum" > 627 < / span > < span class = "lineCov" > 573582 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "628" > < span class = "lineNum" > 628 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "629" > < span class = "lineNum" > 629 < / span > : log_tag(" parity_%s:%u:%s: Write error. %s.\n" , es(errno), blockcur, lev_config_name(level), strerror(errno));< / a >
< a name = "630" > < span class = "lineNum" > 630 < / span > : < / a >
< a name = "631" > < span class = "lineNum" > 631 < / span > : if (is_hw(errno)) {< / a >
< a name = "632" > < span class = "lineNum" > 632 < / span > : log_error_errno(errno, lev_config_name(level));< / a >
< a name = "633" > < span class = "lineNum" > 633 < / span > : /* continue until the error limit is reached */< / a >
< a name = "634" > < span class = "lineNum" > 634 < / span > : task-> state = TASK_STATE_IOERROR_CONTINUE;< / a >
< a name = "635" > < span class = "lineNum" > 635 < / span > : } else {< / a >
< a name = "636" > < span class = "lineNum" > 636 < / span > : log_fatal_errno(errno, lev_config_name(level));< / a >
< a name = "637" > < span class = "lineNum" > 637 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "638" > < span class = "lineNum" > 638 < / span > : task-> state = TASK_STATE_ERROR;< / a >
< a name = "639" > < span class = "lineNum" > 639 < / span > : }< / a >
< a name = "640" > < span class = "lineNum" > 640 < / span > : return;< / a >
< a name = "641" > < span class = "lineNum" > 641 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "642" > < span class = "lineNum" > 642 < / span > : }< / a >
< a name = "643" > < span class = "lineNum" > 643 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "644" > < span class = "lineNum" > 644 < / span > < span class = "lineCov" > 573582 : task-> state = TASK_STATE_DONE;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "645" > < span class = "lineNum" > 645 < / span > : }< / a >
< a name = "646" > < span class = "lineNum" > 646 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "647" > < span class = "lineNum" > 647 < / span > < span class = "lineCov" > 92 : static int state_sync_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "648" > < span class = "lineNum" > 648 < / span > : {< / a >
< a name = "649" > < span class = "lineNum" > 649 < / span > : struct snapraid_io io;< / a >
< a name = "650" > < span class = "lineNum" > 650 < / span > : struct snapraid_plan plan;< / a >
< a name = "651" > < span class = "lineNum" > 651 < / span > : struct snapraid_handle* handle;< / a >
< a name = "652" > < span class = "lineNum" > 652 < / span > : void* rehandle_alloc;< / a >
< a name = "653" > < span class = "lineNum" > 653 < / span > : struct snapraid_rehash* rehandle;< / a >
< a name = "654" > < span class = "lineNum" > 654 < / span > : unsigned diskmax;< / a >
< a name = "655" > < span class = "lineNum" > 655 < / span > : block_off_t blockcur;< / a >
< a name = "656" > < span class = "lineNum" > 656 < / span > : unsigned j;< / a >
< a name = "657" > < span class = "lineNum" > 657 < / span > : void* zero_alloc;< / a >
< a name = "658" > < span class = "lineNum" > 658 < / span > : void** zero;< / a >
< a name = "659" > < span class = "lineNum" > 659 < / span > : void* copy_alloc;< / a >
< a name = "660" > < span class = "lineNum" > 660 < / span > : void** copy;< / a >
< a name = "661" > < span class = "lineNum" > 661 < / span > : unsigned buffermax;< / a >
< a name = "662" > < span class = "lineNum" > 662 < / span > : data_off_t countsize;< / a >
< a name = "663" > < span class = "lineNum" > 663 < / span > : block_off_t countpos;< / a >
< a name = "664" > < span class = "lineNum" > 664 < / span > : block_off_t countmax;< / a >
< a name = "665" > < span class = "lineNum" > 665 < / span > : block_off_t autosavedone;< / a >
< a name = "666" > < span class = "lineNum" > 666 < / span > : block_off_t autosavelimit;< / a >
< a name = "667" > < span class = "lineNum" > 667 < / span > : block_off_t autosavemissing;< / a >
< a name = "668" > < span class = "lineNum" > 668 < / span > : int ret;< / a >
< a name = "669" > < span class = "lineNum" > 669 < / span > : unsigned soft_error;< / a >
< a name = "670" > < span class = "lineNum" > 670 < / span > : unsigned silent_error;< / a >
< a name = "671" > < span class = "lineNum" > 671 < / span > : unsigned io_error;< / a >
< a name = "672" > < span class = "lineNum" > 672 < / span > : time_t now;< / a >
< a name = "673" > < span class = "lineNum" > 673 < / span > : struct failed_struct* failed;< / a >
< a name = "674" > < span class = "lineNum" > 674 < / span > : int* failed_map;< / a >
< a name = "675" > < span class = "lineNum" > 675 < / span > : unsigned l;< / a >
< a name = "676" > < span class = "lineNum" > 676 < / span > : unsigned* waiting_map;< / a >
< a name = "677" > < span class = "lineNum" > 677 < / span > : unsigned waiting_mac;< / a >
< a name = "678" > < span class = "lineNum" > 678 < / span > : char esc_buffer[ESC_MAX];< / a >
< a name = "679" > < span class = "lineNum" > 679 < / span > : bit_vect_t* block_enabled;< / a >
< a name = "680" > < span class = "lineNum" > 680 < / span > : < / a >
< a name = "681" > < span class = "lineNum" > 681 < / span > : /* the sync process assumes that all the hashes are correct */< / a >
< a name = "682" > < span class = "lineNum" > 682 < / span > : /* including the ones from CHG and DELETED blocks */< / a >
2026-02-28 16:47:55 +01:00
< a name = "683" > < span class = "lineNum" > 683 < / span > < span class = "lineCov" > 92 : assert(state-> clear_past_hash != 0);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "684" > < span class = "lineNum" > 684 < / span > : < / a >
< a name = "685" > < span class = "lineNum" > 685 < / span > : /* get the present time */< / a >
2026-02-28 16:47:55 +01:00
< a name = "686" > < span class = "lineNum" > 686 < / span > < span class = "lineCov" > 92 : now = time(0);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "687" > < span class = "lineNum" > 687 < / span > : < / a >
< a name = "688" > < span class = "lineNum" > 688 < / span > : /* maps the disks to handles */< / a >
2026-02-28 16:47:55 +01:00
< a name = "689" > < span class = "lineNum" > 689 < / span > < span class = "lineCov" > 92 : handle = handle_mapping(state, & diskmax);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "690" > < span class = "lineNum" > 690 < / span > : < / a >
< a name = "691" > < span class = "lineNum" > 691 < / span > : /* rehash buffers */< / a >
2026-02-28 16:47:55 +01:00
< a name = "692" > < span class = "lineNum" > 692 < / span > < span class = "lineCov" > 92 : rehandle = malloc_nofail_align(diskmax * sizeof(struct snapraid_rehash), & rehandle_alloc);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "693" > < span class = "lineNum" > 693 < / span > : < / a >
< a name = "694" > < span class = "lineNum" > 694 < / span > : /* we need 1 * data + 1 * parity */< / a >
2026-02-28 16:47:55 +01:00
< a name = "695" > < span class = "lineNum" > 695 < / span > < span class = "lineCov" > 92 : buffermax = diskmax + state-> level;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "696" > < span class = "lineNum" > 696 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "697" > < span class = "lineNum" > 697 < / span > : /* initialize the io threads */< / a >
2026-02-28 16:47:55 +01:00
< a name = "698" > < span class = "lineNum" > 698 < / span > < span class = "lineCov" > 92 : io_init(& io, state, state-> opt.io_cache, buffermax, sync_data_reader, handle, diskmax, 0, sync_parity_writer, parity_handle, state-> level);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "699" > < span class = "lineNum" > 699 < / span > : < / a >
< a name = "700" > < span class = "lineNum" > 700 < / span > : /* allocate the copy buffer */< / a >
2026-02-28 16:47:55 +01:00
< a name = "701" > < span class = "lineNum" > 701 < / span > < span class = "lineCov" > 92 : copy = malloc_nofail_vector_align(diskmax, diskmax, state-> block_size, & copy_alloc);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "702" > < span class = "lineNum" > 702 < / span > : < / a >
< a name = "703" > < span class = "lineNum" > 703 < / span > : /* allocate and fill the zero buffer */< / a >
2026-02-28 16:47:55 +01:00
< a name = "704" > < span class = "lineNum" > 704 < / span > < span class = "lineCov" > 92 : zero = malloc_nofail_align(state-> block_size, & zero_alloc);< / span > < / a >
< a name = "705" > < span class = "lineNum" > 705 < / span > < span class = "lineCov" > 92 : memset(zero, 0, state-> block_size);< / span > < / a >
< a name = "706" > < span class = "lineNum" > 706 < / span > < span class = "lineCov" > 92 : raid_zero(zero);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "707" > < span class = "lineNum" > 707 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "708" > < span class = "lineNum" > 708 < / span > < span class = "lineCov" > 92 : failed = malloc_nofail(diskmax * sizeof(struct failed_struct));< / span > < / a >
< a name = "709" > < span class = "lineNum" > 709 < / span > < span class = "lineCov" > 92 : failed_map = malloc_nofail(diskmax * sizeof(unsigned));< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "710" > < span class = "lineNum" > 710 < / span > : < / a >
< a name = "711" > < span class = "lineNum" > 711 < / span > : /* possibly waiting disks */< / a >
2026-02-28 16:47:55 +01:00
< a name = "712" > < span class = "lineNum" > 712 < / span > < span class = "lineCov" > 92 : waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX;< / span > < / a >
< a name = "713" > < span class = "lineNum" > 713 < / span > < span class = "lineCov" > 92 : waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned));< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "714" > < span class = "lineNum" > 714 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "715" > < span class = "lineNum" > 715 < / span > < span class = "lineCov" > 92 : soft_error = 0;< / span > < / a >
< a name = "716" > < span class = "lineNum" > 716 < / span > < span class = "lineCov" > 92 : silent_error = 0;< / span > < / a >
< a name = "717" > < span class = "lineNum" > 717 < / span > < span class = "lineCov" > 92 : io_error = 0;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "718" > < span class = "lineNum" > 718 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "719" > < span class = "lineNum" > 719 < / span > < span class = "lineCov" > 92 : msg_progress(" Selecting...\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "720" > < span class = "lineNum" > 720 < / span > : < / a >
< a name = "721" > < span class = "lineNum" > 721 < / span > : /* first count the number of blocks to process */< / a >
2026-02-28 16:47:55 +01:00
< a name = "722" > < span class = "lineNum" > 722 < / span > < span class = "lineCov" > 92 : countmax = 0;< / span > < / a >
< a name = "723" > < span class = "lineNum" > 723 < / span > < span class = "lineCov" > 92 : plan.handle_max = diskmax;< / span > < / a >
< a name = "724" > < span class = "lineNum" > 724 < / span > < span class = "lineCov" > 92 : plan.handle_map = handle;< / span > < / a >
< a name = "725" > < span class = "lineNum" > 725 < / span > < span class = "lineCov" > 92 : plan.force_full = state-> opt.force_full;< / span > < / a >
< a name = "726" > < span class = "lineNum" > 726 < / span > < span class = "lineCov" > 92 : block_enabled = calloc_nofail(1, bit_vect_size(blockmax)); /* preinitialize to 0 */< / span > < / a >
< a name = "727" > < span class = "lineNum" > 727 < / span > < span class = "lineCov" > 463206 : for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {< / span > < / a >
< a name = "728" > < span class = "lineNum" > 728 < / span > < span class = "lineCov" > 463114 : if (!block_is_enabled(& plan, blockcur))< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "729" > < span class = "lineNum" > 729 < / span > < span class = "lineCov" > 337042 : continue;< / span > < / a >
< a name = "730" > < span class = "lineNum" > 730 < / span > < span class = "lineCov" > 126072 : bit_vect_set(block_enabled, blockcur);< / span > < / a >
< a name = "731" > < span class = "lineNum" > 731 < / span > < span class = "lineCov" > 126072 : ++countmax;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "732" > < span class = "lineNum" > 732 < / span > : }< / a >
< a name = "733" > < span class = "lineNum" > 733 < / span > : < / a >
< a name = "734" > < span class = "lineNum" > 734 < / span > : /* compute the autosave size for all disk, even if not read */< / a >
< a name = "735" > < span class = "lineNum" > 735 < / span > : /* this makes sense because the speed should be almost the same */< / a >
< a name = "736" > < span class = "lineNum" > 736 < / span > : /* if the disks are read in parallel */< / a >
2026-02-28 16:47:55 +01:00
< a name = "737" > < span class = "lineNum" > 737 < / span > < span class = "lineCov" > 92 : autosavelimit = state-> autosave / (diskmax * state-> block_size);< / span > < / a >
< a name = "738" > < span class = "lineNum" > 738 < / span > < span class = "lineCov" > 92 : autosavemissing = countmax; /* blocks to do */< / span > < / a >
< a name = "739" > < span class = "lineNum" > 739 < / span > < span class = "lineCov" > 92 : autosavedone = 0; /* blocks done */< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "740" > < span class = "lineNum" > 740 < / span > : < / a >
< a name = "741" > < span class = "lineNum" > 741 < / span > : /* drop until now */< / a >
2026-02-28 16:47:55 +01:00
< a name = "742" > < span class = "lineNum" > 742 < / span > < span class = "lineCov" > 92 : state_usage_waste(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "743" > < span class = "lineNum" > 743 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "744" > < span class = "lineNum" > 744 < / span > < span class = "lineCov" > 92 : countsize = 0;< / span > < / a >
< a name = "745" > < span class = "lineNum" > 745 < / span > < span class = "lineCov" > 92 : countpos = 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "746" > < span class = "lineNum" > 746 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "747" > < span class = "lineNum" > 747 < / span > < span class = "lineCov" > 92 : msg_progress(" Syncing...\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "748" > < span class = "lineNum" > 748 < / span > : < / a >
< a name = "749" > < span class = "lineNum" > 749 < / span > : /* start all the worker threads */< / a >
2026-02-28 16:47:55 +01:00
< a name = "750" > < span class = "lineNum" > 750 < / span > < span class = "lineCov" > 92 : io_start(& io, blockstart, blockmax, block_enabled);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "751" > < span class = "lineNum" > 751 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "752" > < span class = "lineNum" > 752 < / span > < span class = "lineCov" > 92 : int alert = state_progress_begin(state, blockstart, blockmax, countmax);< / span > < / a >
< a name = "753" > < span class = "lineNum" > 753 < / span > < span class = "lineCov" > 92 : if (alert > 0)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "754" > < span class = "lineNum" > 754 < / span > < span class = "lineNoCov" > 0 : goto end;< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "755" > < span class = "lineNum" > 755 < / span > < span class = "lineCov" > 92 : if (alert < 0)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "756" > < span class = "lineNum" > 756 < / span > < span class = "lineNoCov" > 0 : goto bail;< / span > < / a >
< a name = "757" > < span class = "lineNum" > 757 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "758" > < span class = "lineNum" > 758 < / span > < span class = "lineCov" > 126072 : while (1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "759" > < span class = "lineNum" > 759 < / span > : unsigned failed_count;< / a >
< a name = "760" > < span class = "lineNum" > 760 < / span > : int error_on_this_block;< / a >
< a name = "761" > < span class = "lineNum" > 761 < / span > : int silent_error_on_this_block;< / a >
< a name = "762" > < span class = "lineNum" > 762 < / span > : int io_error_on_this_block;< / a >
< a name = "763" > < span class = "lineNum" > 763 < / span > : int fixed_error_on_this_block;< / a >
< a name = "764" > < span class = "lineNum" > 764 < / span > : int parity_needs_to_be_updated;< / a >
< a name = "765" > < span class = "lineNum" > 765 < / span > : int parity_going_to_be_updated;< / a >
< a name = "766" > < span class = "lineNum" > 766 < / span > : snapraid_info info;< / a >
< a name = "767" > < span class = "lineNum" > 767 < / span > : int rehash;< / a >
< a name = "768" > < span class = "lineNum" > 768 < / span > : void** buffer;< / a >
< a name = "769" > < span class = "lineNum" > 769 < / span > : int writer_error[IO_WRITER_ERROR_MAX];< / a >
2025-10-28 12:01:21 +01:00
< a name = "770" > < span class = "lineNum" > 770 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "771" > < span class = "lineNum" > 771 < / span > : /* go to the next block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "772" > < span class = "lineNum" > 772 < / span > < span class = "lineCov" > 126164 : blockcur = io_read_next(& io, & buffer);< / span > < / a >
< a name = "773" > < span class = "lineNum" > 773 < / span > < span class = "lineCov" > 126164 : if (blockcur > = blockmax)< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "774" > < span class = "lineNum" > 774 < / span > < span class = "lineCov" > 92 : break;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "775" > < span class = "lineNum" > 775 < / span > : < / a >
< a name = "776" > < span class = "lineNum" > 776 < / span > : /* until now is scheduling */< / a >
2026-03-15 18:52:43 +01:00
< a name = "777" > < span class = "lineNum" > 777 < / span > < span class = "lineCov" > 126072 : state_usage_sched(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "778" > < span class = "lineNum" > 778 < / span > : < / a >
< a name = "779" > < span class = "lineNum" > 779 < / span > : /* one more block processed for autosave */< / a >
2026-03-15 18:52:43 +01:00
< a name = "780" > < span class = "lineNum" > 780 < / span > < span class = "lineCov" > 126072 : ++autosavedone;< / span > < / a >
< a name = "781" > < span class = "lineNum" > 781 < / span > < span class = "lineCov" > 126072 : --autosavemissing;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "782" > < span class = "lineNum" > 782 < / span > : < / a >
< a name = "783" > < span class = "lineNum" > 783 < / span > : /* by default process the block, and skip it if something goes wrong */< / a >
2026-03-15 18:52:43 +01:00
< a name = "784" > < span class = "lineNum" > 784 < / span > < span class = "lineCov" > 126072 : error_on_this_block = 0;< / span > < / a >
< a name = "785" > < span class = "lineNum" > 785 < / span > < span class = "lineCov" > 126072 : silent_error_on_this_block = 0;< / span > < / a >
< a name = "786" > < span class = "lineNum" > 786 < / span > < span class = "lineCov" > 126072 : io_error_on_this_block = 0;< / span > < / a >
< a name = "787" > < span class = "lineNum" > 787 < / span > < span class = "lineCov" > 126072 : fixed_error_on_this_block = 0;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "788" > < span class = "lineNum" > 788 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "789" > < span class = "lineNum" > 789 < / span > : /* keep track of the number of failed blocks */< / a >
2026-03-15 18:52:43 +01:00
< a name = "790" > < span class = "lineNum" > 790 < / span > < span class = "lineCov" > 126072 : failed_count = 0;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "791" > < span class = "lineNum" > 791 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "792" > < span class = "lineNum" > 792 < / span > : /* get block specific info */< / a >
2026-03-15 18:52:43 +01:00
< a name = "793" > < span class = "lineNum" > 793 < / span > < span class = "lineCov" > 126072 : info = info_get(& state-> infoarr, blockcur);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "794" > < span class = "lineNum" > 794 < / span > : < / a >
< a name = "795" > < span class = "lineNum" > 795 < / span > : /* if we have to use the old hash */< / a >
2026-03-15 18:52:43 +01:00
< a name = "796" > < span class = "lineNum" > 796 < / span > < span class = "lineCov" > 126072 : rehash = info_get_rehash(info);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "797" > < span class = "lineNum" > 797 < / span > : < / a >
< a name = "798" > < span class = "lineNum" > 798 < / span > : /* if the parity requires to be updated */< / a >
< a name = "799" > < span class = "lineNum" > 799 < / span > : /* It could happens that all the blocks are EMPTY/BLK and CHG but with the hash */< / a >
< a name = "800" > < span class = "lineNum" > 800 < / span > : /* still matching because the specific CHG block was not modified. */< / a >
< a name = "801" > < span class = "lineNum" > 801 < / span > : /* In such case, we can avoid to update parity, because it would be the same as before */< / a >
< a name = "802" > < span class = "lineNum" > 802 < / span > : /* Note that CHG/DELETED blocks already present in the content file loaded */< / a >
< a name = "803" > < span class = "lineNum" > 803 < / span > : /* have the hash cleared (::clear_past_hash flag), and then they won't never match the hash. */< / a >
< a name = "804" > < span class = "lineNum" > 804 < / span > : /* We are treating only CHG blocks created at runtime. */< / a >
2026-03-15 18:52:43 +01:00
< a name = "805" > < span class = "lineNum" > 805 < / span > < span class = "lineCov" > 126072 : parity_needs_to_be_updated = state-> opt.force_full || state-> opt.force_parity_update;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "806" > < span class = "lineNum" > 806 < / span > : < / a >
< a name = "807" > < span class = "lineNum" > 807 < / span > : /* if the parity is going to be updated */< / a >
2026-03-15 18:52:43 +01:00
< a name = "808" > < span class = "lineNum" > 808 < / span > < span class = "lineCov" > 126072 : parity_going_to_be_updated = 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "809" > < span class = "lineNum" > 809 < / span > : < / a >
< a name = "810" > < span class = "lineNum" > 810 < / span > : /* if the block is marked as bad, we force the parity update */< / a >
< a name = "811" > < span class = "lineNum" > 811 < / span > : /* because the bad block may be the result of a wrong parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "812" > < span class = "lineNum" > 812 < / span > < span class = "lineCov" > 126072 : if (info_get_bad(info))< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "813" > < span class = "lineNum" > 813 < / span > < span class = "lineNoCov" > 0 : parity_needs_to_be_updated = 1;< / span > < / a >
< a name = "814" > < span class = "lineNum" > 814 < / span > : < / a >
< a name = "815" > < span class = "lineNum" > 815 < / span > : /* for each disk, process the block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "816" > < span class = "lineNum" > 816 < / span > < span class = "lineCov" > 882504 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "817" > < span class = "lineNum" > 817 < / span > : struct snapraid_task* task;< / a >
< a name = "818" > < span class = "lineNum" > 818 < / span > : int read_size;< / a >
< a name = "819" > < span class = "lineNum" > 819 < / span > : unsigned char hash[HASH_MAX];< / a >
< a name = "820" > < span class = "lineNum" > 820 < / span > : struct snapraid_block* block;< / a >
< a name = "821" > < span class = "lineNum" > 821 < / span > : unsigned block_state;< / a >
< a name = "822" > < span class = "lineNum" > 822 < / span > : struct snapraid_disk* disk;< / a >
< a name = "823" > < span class = "lineNum" > 823 < / span > : struct snapraid_file* file;< / a >
< a name = "824" > < span class = "lineNum" > 824 < / span > : block_off_t file_pos;< / a >
< a name = "825" > < span class = "lineNum" > 825 < / span > : unsigned diskcur;< / a >
< a name = "826" > < span class = "lineNum" > 826 < / span > : < / a >
< a name = "827" > < span class = "lineNum" > 827 < / span > : /* until now is misc */< / a >
2026-03-15 18:52:43 +01:00
< a name = "828" > < span class = "lineNum" > 828 < / span > < span class = "lineCov" > 756432 : state_usage_misc(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "829" > < span class = "lineNum" > 829 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "830" > < span class = "lineNum" > 830 < / span > < span class = "lineCov" > 756432 : task = io_data_read(& io, & diskcur, waiting_map, & waiting_mac);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "831" > < span class = "lineNum" > 831 < / span > : < / a >
< a name = "832" > < span class = "lineNum" > 832 < / span > : /* until now is disk */< / a >
2026-03-15 18:52:43 +01:00
< a name = "833" > < span class = "lineNum" > 833 < / span > < span class = "lineCov" > 756432 : state_usage_disk(state, handle, waiting_map, waiting_mac);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "834" > < span class = "lineNum" > 834 < / span > : < / a >
< a name = "835" > < span class = "lineNum" > 835 < / span > : /* get the results */< / a >
2026-03-15 18:52:43 +01:00
< a name = "836" > < span class = "lineNum" > 836 < / span > < span class = "lineCov" > 756432 : disk = task-> disk;< / span > < / a >
< a name = "837" > < span class = "lineNum" > 837 < / span > < span class = "lineCov" > 756432 : block = task-> block;< / span > < / a >
< a name = "838" > < span class = "lineNum" > 838 < / span > < span class = "lineCov" > 756432 : file = task-> file;< / span > < / a >
< a name = "839" > < span class = "lineNum" > 839 < / span > < span class = "lineCov" > 756432 : file_pos = task-> file_pos;< / span > < / a >
< a name = "840" > < span class = "lineNum" > 840 < / span > < span class = "lineCov" > 756432 : read_size = task-> read_size;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "841" > < span class = "lineNum" > 841 < / span > : < / a >
< a name = "842" > < span class = "lineNum" > 842 < / span > : /* by default no rehash in case of " continue" */< / a >
2026-03-15 18:52:43 +01:00
< a name = "843" > < span class = "lineNum" > 843 < / span > < span class = "lineCov" > 756432 : rehandle[diskcur].block = 0;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "844" > < span class = "lineNum" > 844 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "845" > < span class = "lineNum" > 845 < / span > : /* if the disk position is not used */< / a >
2026-03-15 18:52:43 +01:00
< a name = "846" > < span class = "lineNum" > 846 < / span > < span class = "lineCov" > 756432 : if (!disk)< / span > < / a >
< a name = "847" > < span class = "lineNum" > 847 < / span > < span class = "lineCov" > 111489 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "848" > < span class = "lineNum" > 848 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "849" > < span class = "lineNum" > 849 < / span > < span class = "lineCov" > 756432 : state_usage_file(state, disk, file);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "850" > < span class = "lineNum" > 850 < / span > : < / a >
< a name = "851" > < span class = "lineNum" > 851 < / span > : /* get the state of the block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "852" > < span class = "lineNum" > 852 < / span > < span class = "lineCov" > 756432 : block_state = block_state_get(block);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "853" > < span class = "lineNum" > 853 < / span > : < / a >
< a name = "854" > < span class = "lineNum" > 854 < / span > : /* if the block has invalid parity, */< / a >
< a name = "855" > < span class = "lineNum" > 855 < / span > : /* we have to take care of it in case of recover */< / a >
2026-03-15 18:52:43 +01:00
< a name = "856" > < span class = "lineNum" > 856 < / span > < span class = "lineCov" > 756432 : if (block_has_invalid_parity(block)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "857" > < span class = "lineNum" > 857 < / span > : /* store it in the failed set, because */< / a >
< a name = "858" > < span class = "lineNum" > 858 < / span > : /* the parity may be still computed with the previous content */< / a >
2026-03-15 18:52:43 +01:00
< a name = "859" > < span class = "lineNum" > 859 < / span > < span class = "lineCov" > 182050 : failed[failed_count].index = diskcur;< / span > < / a >
< a name = "860" > < span class = "lineNum" > 860 < / span > < span class = "lineCov" > 182050 : failed[failed_count].size = state-> block_size;< / span > < / a >
< a name = "861" > < span class = "lineNum" > 861 < / span > < span class = "lineCov" > 182050 : failed[failed_count].block = block;< / span > < / a >
< a name = "862" > < span class = "lineNum" > 862 < / span > < span class = "lineCov" > 182050 : ++failed_count;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "863" > < span class = "lineNum" > 863 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "864" > < span class = "lineNum" > 864 < / span > : /* if the block has invalid parity, we have to update the parity */< / a >
< a name = "865" > < span class = "lineNum" > 865 < / span > : /* to include this block change */< / a >
< a name = "866" > < span class = "lineNum" > 866 < / span > : /* This also apply to CHG blocks, but we are going to handle */< / a >
< a name = "867" > < span class = "lineNum" > 867 < / span > : /* later this case to do the updates only if really needed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "868" > < span class = "lineNum" > 868 < / span > < span class = "lineCov" > 182050 : if (block_state != BLOCK_STATE_CHG)< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "869" > < span class = "lineNum" > 869 < / span > < span class = "lineCov" > 89762 : parity_needs_to_be_updated = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "870" > < span class = "lineNum" > 870 < / span > : < / a >
< a name = "871" > < span class = "lineNum" > 871 < / span > : /* note that DELETE blocks are skipped in the next check */< / a >
< a name = "872" > < span class = "lineNum" > 872 < / span > : /* and we have to store them in the failed blocks */< / a >
< a name = "873" > < span class = "lineNum" > 873 < / span > : /* before skipping */< / a >
< a name = "874" > < span class = "lineNum" > 874 < / span > : < / a >
< a name = "875" > < span class = "lineNum" > 875 < / span > : /* follow */< / a >
< a name = "876" > < span class = "lineNum" > 876 < / span > : }< / a >
< a name = "877" > < span class = "lineNum" > 877 < / span > : < / a >
< a name = "878" > < span class = "lineNum" > 878 < / span > : /* if the block is not used */< / a >
2026-03-15 18:52:43 +01:00
< a name = "879" > < span class = "lineNum" > 879 < / span > < span class = "lineCov" > 756432 : if (!block_has_file(block))< / span > < / a >
< a name = "880" > < span class = "lineNum" > 880 < / span > < span class = "lineCov" > 110618 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "881" > < span class = "lineNum" > 881 < / span > : < / a >
< a name = "882" > < span class = "lineNum" > 882 < / span > : /* handle error conditions */< / a >
2026-03-15 18:52:43 +01:00
< a name = "883" > < span class = "lineNum" > 883 < / span > < span class = "lineCov" > 645814 : if (task-> state == TASK_STATE_IOERROR) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "884" > < span class = "lineNum" > 884 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "885" > < span class = "lineNum" > 885 < / span > : ++io_error;< / a >
< a name = "886" > < span class = "lineNum" > 886 < / span > : goto bail;< / a >
< a name = "887" > < span class = "lineNum" > 887 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "888" > < span class = "lineNum" > 888 < / span > : }< / a >
2026-03-15 18:52:43 +01:00
< a name = "889" > < span class = "lineNum" > 889 < / span > < span class = "lineCov" > 645814 : if (task-> state == TASK_STATE_ERROR) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "890" > < span class = "lineNum" > 890 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "891" > < span class = "lineNum" > 891 < / span > : ++soft_error;< / a >
< a name = "892" > < span class = "lineNum" > 892 < / span > : goto bail;< / a >
< a name = "893" > < span class = "lineNum" > 893 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "894" > < span class = "lineNum" > 894 < / span > : }< / a >
2026-03-15 18:52:43 +01:00
< a name = "895" > < span class = "lineNum" > 895 < / span > < span class = "lineCov" > 645814 : if (task-> state == TASK_STATE_ERROR_CONTINUE) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "896" > < span class = "lineNum" > 896 < / span > < span class = "lineCov" > 18 : ++soft_error;< / span > < / a >
< a name = "897" > < span class = "lineNum" > 897 < / span > < span class = "lineCov" > 18 : error_on_this_block = 1;< / span > < / a >
< a name = "898" > < span class = "lineNum" > 898 < / span > < span class = "lineCov" > 18 : continue;< / span > < / a >
< a name = "899" > < span class = "lineNum" > 899 < / span > : }< / a >
2026-03-15 18:52:43 +01:00
< a name = "900" > < span class = "lineNum" > 900 < / span > < span class = "lineCov" > 645796 : if (task-> state == TASK_STATE_IOERROR_CONTINUE) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "901" > < span class = "lineNum" > 901 < / span > < span class = "lineNoCov" > 0 : ++io_error;< / span > < / a >
< a name = "902" > < span class = "lineNum" > 902 < / span > < span class = "lineNoCov" > 0 : if (io_error > = state-> opt.io_error_limit) {< / span > < / a >
< a name = "903" > < span class = "lineNum" > 903 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "904" > < span class = "lineNum" > 904 < / span > : log_fatal(EIO, " DANGER! Too many input/output errors in the %s disk. It isn't possible to continue.\n" , disk-> dir);< / a >
< a name = "905" > < span class = "lineNum" > 905 < / span > : log_fatal(EIO, " Stopping at block %u\n" , blockcur);< / a >
< a name = "906" > < span class = "lineNum" > 906 < / span > : goto bail;< / a >
< a name = "907" > < span class = "lineNum" > 907 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "908" > < span class = "lineNum" > 908 < / span > : }< / a >
< a name = "909" > < span class = "lineNum" > 909 < / span > : < / a >
< a name = "910" > < span class = "lineNum" > 910 < / span > : /* otherwise continue */< / a >
< a name = "911" > < span class = "lineNum" > 911 < / span > < span class = "lineNoCov" > 0 : io_error_on_this_block = 1;< / span > < / a >
< a name = "912" > < span class = "lineNum" > 912 < / span > < span class = "lineNoCov" > 0 : continue;< / span > < / a >
< a name = "913" > < span class = "lineNum" > 913 < / span > : }< / a >
2026-03-15 18:52:43 +01:00
< a name = "914" > < span class = "lineNum" > 914 < / span > < span class = "lineCov" > 645796 : if (task-> state != TASK_STATE_DONE) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "915" > < span class = "lineNum" > 915 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "916" > < span class = "lineNum" > 916 < / span > : log_fatal(EINTERNAL, " Internal inconsistency in task state\n" );< / a >
< a name = "917" > < span class = "lineNum" > 917 < / span > : os_abort();< / a >
< a name = "918" > < span class = "lineNum" > 918 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "919" > < span class = "lineNum" > 919 < / span > : }< / a >
< a name = "920" > < span class = "lineNum" > 920 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "921" > < span class = "lineNum" > 921 < / span > < span class = "lineCov" > 645796 : countsize += read_size;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "922" > < span class = "lineNum" > 922 < / span > : < / a >
< a name = "923" > < span class = "lineNum" > 923 < / span > : /* now compute the hash */< / a >
2026-03-15 18:52:43 +01:00
< a name = "924" > < span class = "lineNum" > 924 < / span > < span class = "lineCov" > 645796 : if (rehash) {< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "925" > < span class = "lineNum" > 925 < / span > < span class = "lineCov" > 27200 : memhash(state-> prevhash, state-> prevhashseed, hash, buffer[diskcur], read_size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "926" > < span class = "lineNum" > 926 < / span > : < / a >
< a name = "927" > < span class = "lineNum" > 927 < / span > : /* compute the new hash, and store it */< / a >
2026-02-28 16:47:55 +01:00
< a name = "928" > < span class = "lineNum" > 928 < / span > < span class = "lineCov" > 27200 : rehandle[diskcur].block = block;< / span > < / a >
< a name = "929" > < span class = "lineNum" > 929 < / span > < span class = "lineCov" > 27200 : memhash(state-> hash, state-> hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "930" > < span class = "lineNum" > 930 < / span > : } else {< / a >
2026-03-15 18:52:43 +01:00
< a name = "931" > < span class = "lineNum" > 931 < / span > < span class = "lineCov" > 618596 : memhash(state-> hash, state-> hashseed, hash, buffer[diskcur], read_size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "932" > < span class = "lineNum" > 932 < / span > : }< / a >
< a name = "933" > < span class = "lineNum" > 933 < / span > : < / a >
< a name = "934" > < span class = "lineNum" > 934 < / span > : /* until now is hash */< / a >
2026-03-15 18:52:43 +01:00
< a name = "935" > < span class = "lineNum" > 935 < / span > < span class = "lineCov" > 645796 : state_usage_hash(state);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "936" > < span class = "lineNum" > 936 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "937" > < span class = "lineNum" > 937 < / span > < span class = "lineCov" > 645796 : if (block_has_updated_hash(block)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "938" > < span class = "lineNum" > 938 < / span > : /* compare the hash */< / a >
2026-03-15 18:52:43 +01:00
< a name = "939" > < span class = "lineNum" > 939 < / span > < span class = "lineCov" > 553526 : if (memcmp(hash, block-> hash, BLOCK_HASH_SIZE) != 0) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "940" > < span class = "lineNum" > 940 < / span > : /* if the file has invalid parity, it's a REP changed during the sync */< / a >
2026-02-28 10:26:32 +01:00
< a name = "941" > < span class = "lineNum" > 941 < / span > < span class = "lineCov" > 853 : if (block_has_invalid_parity(block)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "942" > < span class = "lineNum" > 942 < / span > < span class = "lineCov" > 1 : log_tag(" error:%u:%s:%s: Unexpected data change\n" , blockcur, disk-> name, esc_tag(file-> sub, esc_buffer));< / span > < / a >
< a name = "943" > < span class = "lineNum" > 943 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " Data change at file '%s' at position '%u'\n" , task-> path, file_pos);< / span > < / a >
< a name = "944" > < span class = "lineNum" > 944 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " WARNING! Unexpected data modification of a file without parity!\n" );< / span > < / a >
< a name = "945" > < span class = "lineNum" > 945 < / span > : < / a >
< a name = "946" > < span class = "lineNum" > 946 < / span > < span class = "lineCov" > 1 : if (file_flag_has(file, FILE_IS_COPY)) {< / span > < / a >
< a name = "947" > < span class = "lineNum" > 947 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " This file was detected as a copy of another file with the same name, size,\n" );< / span > < / a >
< a name = "948" > < span class = "lineNum" > 948 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " and timestamp, but the file data isn't matching the assumed copy.\n" );< / span > < / a >
< a name = "949" > < span class = "lineNum" > 949 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " If this is a false positive, and the files are expected to be different,\n" );< / span > < / a >
< a name = "950" > < span class = "lineNum" > 950 < / span > < span class = "lineCov" > 1 : log_error(ESOFT, " you can 'sync' anyway using 'snapraid --force-nocopy sync'\n" );< / span > < / a >
< a name = "951" > < span class = "lineNum" > 951 < / span > : } else {< / a >
< a name = "952" > < span class = "lineNum" > 952 < / span > < span class = "lineNoCov" > 0 : log_error(ESOFT, " Try removing the file from the array and rerun the 'sync' command!\n" );< / span > < / a >
< a name = "953" > < span class = "lineNum" > 953 < / span > : }< / a >
< a name = "954" > < span class = "lineNum" > 954 < / span > : < / a >
< a name = "955" > < span class = "lineNum" > 955 < / span > < span class = "lineCov" > 1 : ++soft_error;< / span > < / a >
< a name = "956" > < span class = "lineNum" > 956 < / span > : < / a >
< a name = "957" > < span class = "lineNum" > 957 < / span > : /* if the file is changed, it means that it was modified during sync */< / a >
< a name = "958" > < span class = "lineNum" > 958 < / span > : /* this isn't a serious error, so we skip this block, and continue with others */< / a >
< a name = "959" > < span class = "lineNum" > 959 < / span > < span class = "lineCov" > 1 : error_on_this_block = 1;< / span > < / a >
< a name = "960" > < span class = "lineNum" > 960 < / span > < span class = "lineCov" > 1 : continue;< / span > < / a >
2026-02-28 10:26:32 +01:00
< a name = "961" > < span class = "lineNum" > 961 < / span > < span class = "lineCov" > 852 : } else { /* otherwise it's a BLK with silent error */< / span > < / a >
< a name = "962" > < span class = "lineNum" > 962 < / span > < span class = "lineCov" > 852 : unsigned diff = memdiff(hash, block-> hash, BLOCK_HASH_SIZE);< / span > < / a >
< a name = "963" > < span class = "lineNum" > 963 < / span > < span class = "lineCov" > 852 : log_tag(" error_data:%u:%s:%s: Data error at position %u, diff hash bits %u/%u\n" , blockcur, disk-> name, esc_tag(file-> sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);< / span > < / a >
< a name = "964" > < span class = "lineNum" > 964 < / span > < span class = "lineCov" > 852 : log_error(EDATA, " Data error in file '%s' at position '%u', diff hash bits %u/%u\n" , task-> path, file_pos, diff, BLOCK_HASH_SIZE * 8);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "965" > < span class = "lineNum" > 965 < / span > : < / a >
< a name = "966" > < span class = "lineNum" > 966 < / span > : /* save the failed block for the fix */< / a >
2026-02-28 10:26:32 +01:00
< a name = "967" > < span class = "lineNum" > 967 < / span > < span class = "lineCov" > 852 : failed[failed_count].index = diskcur;< / span > < / a >
< a name = "968" > < span class = "lineNum" > 968 < / span > < span class = "lineCov" > 852 : failed[failed_count].size = read_size;< / span > < / a >
< a name = "969" > < span class = "lineNum" > 969 < / span > < span class = "lineCov" > 852 : failed[failed_count].block = block;< / span > < / a >
< a name = "970" > < span class = "lineNum" > 970 < / span > < span class = "lineCov" > 852 : ++failed_count;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "971" > < span class = "lineNum" > 971 < / span > : < / a >
< a name = "972" > < span class = "lineNum" > 972 < / span > : /* silent errors are very rare, and are not a signal that a disk */< / a >
< a name = "973" > < span class = "lineNum" > 973 < / span > : /* is going to fail. So, we just continue marking the block as bad */< / a >
< a name = "974" > < span class = "lineNum" > 974 < / span > : /* just like in scrub */< / a >
2026-02-28 10:26:32 +01:00
< a name = "975" > < span class = "lineNum" > 975 < / span > < span class = "lineCov" > 852 : ++silent_error;< / span > < / a >
< a name = "976" > < span class = "lineNum" > 976 < / span > < span class = "lineCov" > 852 : silent_error_on_this_block = 1;< / span > < / a >
< a name = "977" > < span class = "lineNum" > 977 < / span > < span class = "lineCov" > 852 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "978" > < span class = "lineNum" > 978 < / span > : }< / a >
< a name = "979" > < span class = "lineNum" > 979 < / span > : }< / a >
< a name = "980" > < span class = "lineNum" > 980 < / span > : } else {< / a >
< a name = "981" > < span class = "lineNum" > 981 < / span > : /* if until now the parity doesn't need to be updated */< / a >
2026-03-15 18:52:43 +01:00
< a name = "982" > < span class = "lineNum" > 982 < / span > < span class = "lineCov" > 92270 : if (!parity_needs_to_be_updated) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "983" > < span class = "lineNum" > 983 < / span > : /* for sure it's a CHG block, because EMPTY are processed before with " continue" */< / a >
< a name = "984" > < span class = "lineNum" > 984 < / span > : /* and BLK and REP have " block_has_updated_hash()" as 1, and all the others */< / a >
< a name = "985" > < span class = "lineNum" > 985 < / span > : /* have " parity_needs_to_be_updated" already at 1 */< / a >
2026-03-15 18:52:43 +01:00
< a name = "986" > < span class = "lineNum" > 986 < / span > < span class = "lineCov" > 35190 : assert(block_state_get(block) == BLOCK_STATE_CHG);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "987" > < span class = "lineNum" > 987 < / span > : < / a >
< a name = "988" > < span class = "lineNum" > 988 < / span > : /* if the hash represents the data unequivocally */< / a >
2026-03-15 18:52:43 +01:00
< a name = "989" > < span class = "lineNum" > 989 < / span > < span class = "lineCov" > 35190 : if (hash_is_unique(block-> hash)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "990" > < span class = "lineNum" > 990 < / span > : /* check if the hash is changed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "991" > < span class = "lineNum" > 991 < / span > < span class = "lineCov" > 6250 : if (memcmp(hash, block-> hash, BLOCK_HASH_SIZE) != 0) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "992" > < span class = "lineNum" > 992 < / span > : /* the block is different, and we must update parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "993" > < span class = "lineNum" > 993 < / span > < span class = "lineCov" > 5087 : parity_needs_to_be_updated = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "994" > < span class = "lineNum" > 994 < / span > : }< / a >
< a name = "995" > < span class = "lineNum" > 995 < / span > : } else {< / a >
< a name = "996" > < span class = "lineNum" > 996 < / span > : /* if the hash is already invalid, we update parity */< / a >
2026-02-28 16:47:55 +01:00
< a name = "997" > < span class = "lineNum" > 997 < / span > < span class = "lineCov" > 28940 : parity_needs_to_be_updated = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "998" > < span class = "lineNum" > 998 < / span > : }< / a >
< a name = "999" > < span class = "lineNum" > 999 < / span > : }< / a >
< a name = "1000" > < span class = "lineNum" > 1000 < / span > : < / a >
< a name = "1001" > < span class = "lineNum" > 1001 < / span > : /* copy the hash in the block, but doesn't mark the block as hashed */< / a >
< a name = "1002" > < span class = "lineNum" > 1002 < / span > : /* this allow in case of skipped block to do not save the failed computation */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1003" > < span class = "lineNum" > 1003 < / span > < span class = "lineCov" > 92270 : memcpy(block-> hash, hash, BLOCK_HASH_SIZE);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1004" > < span class = "lineNum" > 1004 < / span > : < / a >
< a name = "1005" > < span class = "lineNum" > 1005 < / span > : /* note that in case of rehash, this is the wrong hash, */< / a >
< a name = "1006" > < span class = "lineNum" > 1006 < / span > : /* but it will be overwritten later */< / a >
< a name = "1007" > < span class = "lineNum" > 1007 < / span > : }< / a >
< a name = "1008" > < span class = "lineNum" > 1008 < / span > : }< / a >
< a name = "1009" > < span class = "lineNum" > 1009 < / span > : < / a >
< a name = "1010" > < span class = "lineNum" > 1010 < / span > : /* if we have only silent errors we can try to fix them on-the-fly */< / a >
< a name = "1011" > < span class = "lineNum" > 1011 < / span > : /* note the fix is not written to disk, but used only to */< / a >
< a name = "1012" > < span class = "lineNum" > 1012 < / span > : /* compute the new parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1013" > < span class = "lineNum" > 1013 < / span > < span class = "lineCov" > 126072 : if (!error_on_this_block & & !io_error_on_this_block & & silent_error_on_this_block) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1014" > < span class = "lineNum" > 1014 < / span > : unsigned failed_mac;< / a >
2026-02-28 10:26:32 +01:00
< a name = "1015" > < span class = "lineNum" > 1015 < / span > < span class = "lineCov" > 852 : int something_to_recover = 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1016" > < span class = "lineNum" > 1016 < / span > : < / a >
< a name = "1017" > < span class = "lineNum" > 1017 < / span > : /* sort the failed vector */< / a >
< a name = "1018" > < span class = "lineNum" > 1018 < / span > : /* because with threads it may be in any order */< / a >
< a name = "1019" > < span class = "lineNum" > 1019 < / span > : /* but RAID requires the indexes to be sorted */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1020" > < span class = "lineNum" > 1020 < / span > < span class = "lineCov" > 852 : qsort(failed, failed_count, sizeof(failed[0]), failed_compare_by_index);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1021" > < span class = "lineNum" > 1021 < / span > : < / a >
< a name = "1022" > < span class = "lineNum" > 1022 < / span > : /* setup the blocks to recover */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1023" > < span class = "lineNum" > 1023 < / span > < span class = "lineCov" > 852 : failed_mac = 0;< / span > < / a >
< a name = "1024" > < span class = "lineNum" > 1024 < / span > < span class = "lineCov" > 2556 : for (j = 0; j < failed_count; ++j) {< / span > < / a >
< a name = "1025" > < span class = "lineNum" > 1025 < / span > < span class = "lineCov" > 1704 : unsigned char* block_buffer = buffer[failed[j].index];< / span > < / a >
< a name = "1026" > < span class = "lineNum" > 1026 < / span > < span class = "lineCov" > 1704 : unsigned char* block_copy = copy[failed[j].index];< / span > < / a >
< a name = "1027" > < span class = "lineNum" > 1027 < / span > < span class = "lineCov" > 1704 : unsigned block_state = block_state_get(failed[j].block);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1028" > < span class = "lineNum" > 1028 < / span > : < / a >
< a name = "1029" > < span class = "lineNum" > 1029 < / span > : /* we try to recover only if at least one BLK is present */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1030" > < span class = "lineNum" > 1030 < / span > < span class = "lineCov" > 1704 : if (block_state == BLOCK_STATE_BLK)< / span > < / a >
< a name = "1031" > < span class = "lineNum" > 1031 < / span > < span class = "lineCov" > 852 : something_to_recover = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1032" > < span class = "lineNum" > 1032 < / span > : < / a >
< a name = "1033" > < span class = "lineNum" > 1033 < / span > : /* save a copy of the content just read */< / a >
< a name = "1034" > < span class = "lineNum" > 1034 < / span > : /* that it's going to be overwritten by the recovering function */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1035" > < span class = "lineNum" > 1035 < / span > < span class = "lineCov" > 1704 : memcpy(block_copy, block_buffer, state-> block_size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1036" > < span class = "lineNum" > 1036 < / span > : < / a >
2026-02-28 10:26:32 +01:00
< a name = "1037" > < span class = "lineNum" > 1037 < / span > < span class = "lineCov" > 1704 : if (block_state == BLOCK_STATE_CHG< / span > < / a >
< a name = "1038" > < span class = "lineNum" > 1038 < / span > < span class = "lineCov" > 852 : & & hash_is_zero(failed[j].block-> hash)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1039" > < span class = "lineNum" > 1039 < / span > : ) {< / a >
< a name = "1040" > < span class = "lineNum" > 1040 < / span > : /* if the block was filled with 0, restore this state */< / a >
< a name = "1041" > < span class = "lineNum" > 1041 < / span > : /* and avoid to recover it */< / a >
< a name = "1042" > < span class = "lineNum" > 1042 < / span > < span class = "lineNoCov" > 0 : memset(block_buffer, 0, state-> block_size);< / span > < / a >
< a name = "1043" > < span class = "lineNum" > 1043 < / span > : } else {< / a >
< a name = "1044" > < span class = "lineNum" > 1044 < / span > : /* if we have too many failures, we cannot recover */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1045" > < span class = "lineNum" > 1045 < / span > < span class = "lineCov" > 1704 : if (failed_mac > = state-> level)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1046" > < span class = "lineNum" > 1046 < / span > < span class = "lineNoCov" > 0 : break;< / span > < / a >
< a name = "1047" > < span class = "lineNum" > 1047 < / span > : < / a >
< a name = "1048" > < span class = "lineNum" > 1048 < / span > : /* otherwise it has to be recovered */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1049" > < span class = "lineNum" > 1049 < / span > < span class = "lineCov" > 1704 : failed_map[failed_mac++] = failed[j].index;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1050" > < span class = "lineNum" > 1050 < / span > : }< / a >
< a name = "1051" > < span class = "lineNum" > 1051 < / span > : }< / a >
< a name = "1052" > < span class = "lineNum" > 1052 < / span > : < / a >
< a name = "1053" > < span class = "lineNum" > 1053 < / span > : /* if we have something to recover and enough parity */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1054" > < span class = "lineNum" > 1054 < / span > < span class = "lineCov" > 852 : if (something_to_recover & & j == failed_count) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1055" > < span class = "lineNum" > 1055 < / span > : /* until now is misc */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1056" > < span class = "lineNum" > 1056 < / span > < span class = "lineCov" > 852 : state_usage_misc(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1057" > < span class = "lineNum" > 1057 < / span > : < / a >
< a name = "1058" > < span class = "lineNum" > 1058 < / span > : /* read the parity */< / a >
< a name = "1059" > < span class = "lineNum" > 1059 < / span > : /* we are sure that parity exists because */< / a >
< a name = "1060" > < span class = "lineNum" > 1060 < / span > : /* we have at least one BLK block */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1061" > < span class = "lineNum" > 1061 < / span > < span class = "lineCov" > 5964 : for (l = 0; l < state-> level; ++l) {< / span > < / a >
< a name = "1062" > < span class = "lineNum" > 1062 < / span > < span class = "lineCov" > 5112 : ret = parity_read(& parity_handle[l], blockcur, buffer[diskmax + l], state-> block_size, log_error);< / span > < / a >
< a name = "1063" > < span class = "lineNum" > 1063 < / span > < span class = "lineCov" > 5112 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1064" > < span class = "lineNum" > 1064 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1065" > < span class = "lineNum" > 1065 < / span > : log_tag(" parity_%s:%u:%s: Read error. %s.\n" , es(errno), blockcur, lev_config_name(l), strerror(errno));< / a >
< a name = "1066" > < span class = "lineNum" > 1066 < / span > : if (is_hw(errno)) {< / a >
< a name = "1067" > < span class = "lineNum" > 1067 < / span > : log_error_errno(errno, lev_config_name(l));< / a >
< a name = "1068" > < span class = "lineNum" > 1068 < / span > : if (io_error > = state-> opt.io_error_limit) {< / a >
< a name = "1069" > < span class = "lineNum" > 1069 < / span > : log_fatal(errno, " DANGER! Too many input/output errors in the %s disk. It isn't possible to continue.\n" , lev_config_name(l));< / a >
< a name = "1070" > < span class = "lineNum" > 1070 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "1071" > < span class = "lineNum" > 1071 < / span > : ++io_error;< / a >
< a name = "1072" > < span class = "lineNum" > 1072 < / span > : goto bail;< / a >
< a name = "1073" > < span class = "lineNum" > 1073 < / span > : }< / a >
< a name = "1074" > < span class = "lineNum" > 1074 < / span > : < / a >
< a name = "1075" > < span class = "lineNum" > 1075 < / span > : ++io_error;< / a >
< a name = "1076" > < span class = "lineNum" > 1076 < / span > : io_error_on_this_block = 1;< / a >
< a name = "1077" > < span class = "lineNum" > 1077 < / span > : continue;< / a >
< a name = "1078" > < span class = "lineNum" > 1078 < / span > : }< / a >
< a name = "1079" > < span class = "lineNum" > 1079 < / span > : < / a >
< a name = "1080" > < span class = "lineNum" > 1080 < / span > : log_fatal_errno(errno, lev_config_name(l));< / a >
< a name = "1081" > < span class = "lineNum" > 1081 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "1082" > < span class = "lineNum" > 1082 < / span > : ++soft_error;< / a >
< a name = "1083" > < span class = "lineNum" > 1083 < / span > : goto bail;< / a >
< a name = "1084" > < span class = "lineNum" > 1084 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1085" > < span class = "lineNum" > 1085 < / span > : }< / a >
< a name = "1086" > < span class = "lineNum" > 1086 < / span > : < / a >
< a name = "1087" > < span class = "lineNum" > 1087 < / span > : /* until now is parity */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1088" > < span class = "lineNum" > 1088 < / span > < span class = "lineCov" > 5112 : state_usage_parity(state, & l, 1);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1089" > < span class = "lineNum" > 1089 < / span > : }< / a >
< a name = "1090" > < span class = "lineNum" > 1090 < / span > : < / a >
< a name = "1091" > < span class = "lineNum" > 1091 < / span > : /* if no error in parity read */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1092" > < span class = "lineNum" > 1092 < / span > < span class = "lineCov" > 852 : if (!io_error_on_this_block) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1093" > < span class = "lineNum" > 1093 < / span > : /* try to fix the data */< / a >
< a name = "1094" > < span class = "lineNum" > 1094 < / span > : /* note that this is a simple fix algorithm, that doesn't take into */< / a >
< a name = "1095" > < span class = "lineNum" > 1095 < / span > : /* account the case of a wrong parity */< / a >
< a name = "1096" > < span class = "lineNum" > 1096 < / span > : /* only 'fix' supports the most advanced fixing */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1097" > < span class = "lineNum" > 1097 < / span > < span class = "lineCov" > 852 : raid_rec(failed_mac, failed_map, diskmax, state-> level, state-> block_size, buffer);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1098" > < span class = "lineNum" > 1098 < / span > : < / a >
< a name = "1099" > < span class = "lineNum" > 1099 < / span > : /* until now is raid */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1100" > < span class = "lineNum" > 1100 < / span > < span class = "lineCov" > 852 : state_usage_raid(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1101" > < span class = "lineNum" > 1101 < / span > : < / a >
< a name = "1102" > < span class = "lineNum" > 1102 < / span > : /* check the result and prepare the data */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1103" > < span class = "lineNum" > 1103 < / span > < span class = "lineCov" > 2556 : for (j = 0; j < failed_count; ++j) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1104" > < span class = "lineNum" > 1104 < / span > : unsigned char hash[HASH_MAX];< / a >
2026-02-28 10:26:32 +01:00
< a name = "1105" > < span class = "lineNum" > 1105 < / span > < span class = "lineCov" > 1704 : unsigned char* block_buffer = buffer[failed[j].index];< / span > < / a >
< a name = "1106" > < span class = "lineNum" > 1106 < / span > < span class = "lineCov" > 1704 : unsigned char* block_copy = copy[failed[j].index];< / span > < / a >
< a name = "1107" > < span class = "lineNum" > 1107 < / span > < span class = "lineCov" > 1704 : unsigned block_state = block_state_get(failed[j].block);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1108" > < span class = "lineNum" > 1108 < / span > : < / a >
2026-02-28 10:26:32 +01:00
< a name = "1109" > < span class = "lineNum" > 1109 < / span > < span class = "lineCov" > 1704 : if (block_state == BLOCK_STATE_BLK) {< / span > < / a >
< a name = "1110" > < span class = "lineNum" > 1110 < / span > < span class = "lineCov" > 852 : unsigned size = failed[j].size;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1111" > < span class = "lineNum" > 1111 < / span > : < / a >
< a name = "1112" > < span class = "lineNum" > 1112 < / span > : /* compute the hash of the recovered block */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1113" > < span class = "lineNum" > 1113 < / span > < span class = "lineCov" > 852 : if (rehash) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1114" > < span class = "lineNum" > 1114 < / span > < span class = "lineNoCov" > 0 : memhash(state-> prevhash, state-> prevhashseed, hash, block_buffer, size);< / span > < / a >
< a name = "1115" > < span class = "lineNum" > 1115 < / span > : } else {< / a >
2026-02-28 10:26:32 +01:00
< a name = "1116" > < span class = "lineNum" > 1116 < / span > < span class = "lineCov" > 852 : memhash(state-> hash, state-> hashseed, hash, block_buffer, size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1117" > < span class = "lineNum" > 1117 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1118" > < span class = "lineNum" > 1118 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1119" > < span class = "lineNum" > 1119 < / span > : /* until now is hash */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1120" > < span class = "lineNum" > 1120 < / span > < span class = "lineCov" > 852 : state_usage_hash(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1121" > < span class = "lineNum" > 1121 < / span > : < / a >
< a name = "1122" > < span class = "lineNum" > 1122 < / span > : /* if the hash doesn't match */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1123" > < span class = "lineNum" > 1123 < / span > < span class = "lineCov" > 852 : if (memcmp(hash, failed[j].block-> hash, BLOCK_HASH_SIZE) != 0) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1124" > < span class = "lineNum" > 1124 < / span > : /* we have not recovered */< / a >
< a name = "1125" > < span class = "lineNum" > 1125 < / span > < span class = "lineNoCov" > 0 : break;< / span > < / a >
< a name = "1126" > < span class = "lineNum" > 1126 < / span > : }< / a >
< a name = "1127" > < span class = "lineNum" > 1127 < / span > : < / a >
< a name = "1128" > < span class = "lineNum" > 1128 < / span > : /* pad with 0 if needed */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1129" > < span class = "lineNum" > 1129 < / span > < span class = "lineCov" > 852 : if (size < state-> block_size)< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "1130" > < span class = "lineNum" > 1130 < / span > < span class = "lineCov" > 333 : memset(block_buffer + size, 0, state-> block_size - size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1131" > < span class = "lineNum" > 1131 < / span > : } else {< / a >
< a name = "1132" > < span class = "lineNum" > 1132 < / span > : /* otherwise restore the content */< / a >
< a name = "1133" > < span class = "lineNum" > 1133 < / span > : /* because we are not interested in the old state */< / a >
< a name = "1134" > < span class = "lineNum" > 1134 < / span > : /* that it's recovered for CHG, REP and DELETED blocks */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1135" > < span class = "lineNum" > 1135 < / span > < span class = "lineCov" > 852 : memcpy(block_buffer, block_copy, state-> block_size);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1136" > < span class = "lineNum" > 1136 < / span > : }< / a >
< a name = "1137" > < span class = "lineNum" > 1137 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1138" > < span class = "lineNum" > 1138 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1139" > < span class = "lineNum" > 1139 < / span > : /* if all is processed, we have fixed it */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1140" > < span class = "lineNum" > 1140 < / span > < span class = "lineCov" > 852 : if (j == failed_count)< / span > < / a >
< a name = "1141" > < span class = "lineNum" > 1141 < / span > < span class = "lineCov" > 852 : fixed_error_on_this_block = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1142" > < span class = "lineNum" > 1142 < / span > : }< / a >
< a name = "1143" > < span class = "lineNum" > 1143 < / span > : }< / a >
< a name = "1144" > < span class = "lineNum" > 1144 < / span > : }< / a >
< a name = "1145" > < span class = "lineNum" > 1145 < / span > : < / a >
< a name = "1146" > < span class = "lineNum" > 1146 < / span > : /* if we have read all the data required and it's correct, proceed with the parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1147" > < span class = "lineNum" > 1147 < / span > < span class = "lineCov" > 126072 : if (!error_on_this_block & & !io_error_on_this_block< / span > < / a >
< a name = "1148" > < span class = "lineNum" > 1148 < / span > < span class = "lineCov" > 126053 : & & (!silent_error_on_this_block || fixed_error_on_this_block)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1149" > < span class = "lineNum" > 1149 < / span > : ) {< / a >
< a name = "1150" > < span class = "lineNum" > 1150 < / span > : /* update the parity only if really needed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1151" > < span class = "lineNum" > 1151 < / span > < span class = "lineCov" > 126053 : if (parity_needs_to_be_updated) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1152" > < span class = "lineNum" > 1152 < / span > : /* compute the parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1153" > < span class = "lineNum" > 1153 < / span > < span class = "lineCov" > 125127 : raid_gen(diskmax, state-> level, state-> block_size, buffer);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1154" > < span class = "lineNum" > 1154 < / span > : < / a >
< a name = "1155" > < span class = "lineNum" > 1155 < / span > : /* until now is raid */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1156" > < span class = "lineNum" > 1156 < / span > < span class = "lineCov" > 125127 : state_usage_raid(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1157" > < span class = "lineNum" > 1157 < / span > : < / a >
< a name = "1158" > < span class = "lineNum" > 1158 < / span > : /* mark that the parity is going to be written */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1159" > < span class = "lineNum" > 1159 < / span > < span class = "lineCov" > 125127 : parity_going_to_be_updated = 1;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1160" > < span class = "lineNum" > 1160 < / span > : }< / a >
2026-02-28 09:59:35 +01:00
< a name = "1161" > < span class = "lineNum" > 1161 < / span > : < / a >
< a name = "1162" > < span class = "lineNum" > 1162 < / span > : /* for each disk, mark the blocks as processed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1163" > < span class = "lineNum" > 1163 < / span > < span class = "lineCov" > 882371 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1164" > < span class = "lineNum" > 1164 < / span > : struct snapraid_block* block;< / a >
< a name = "1165" > < span class = "lineNum" > 1165 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "1166" > < span class = "lineNum" > 1166 < / span > < span class = "lineCov" > 756318 : if (!handle[j].disk)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1167" > < span class = "lineNum" > 1167 < / span > < span class = "lineNoCov" > 0 : continue;< / span > < / a >
< a name = "1168" > < span class = "lineNum" > 1168 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "1169" > < span class = "lineNum" > 1169 < / span > < span class = "lineCov" > 756318 : block = fs_par2block_find(handle[j].disk, blockcur);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1170" > < span class = "lineNum" > 1170 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "1171" > < span class = "lineNum" > 1171 < / span > < span class = "lineCov" > 756318 : if (block == BLOCK_NULL) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1172" > < span class = "lineNum" > 1172 < / span > : /* nothing to do */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1173" > < span class = "lineNum" > 1173 < / span > < span class = "lineCov" > 97829 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1174" > < span class = "lineNum" > 1174 < / span > : }< / a >
< a name = "1175" > < span class = "lineNum" > 1175 < / span > : < / a >
< a name = "1176" > < span class = "lineNum" > 1176 < / span > : /* if it's a deleted block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1177" > < span class = "lineNum" > 1177 < / span > < span class = "lineCov" > 658489 : if (block_state_get(block) == BLOCK_STATE_DELETED) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1178" > < span class = "lineNum" > 1178 < / span > : /* the parity is now updated without this block, so it's now empty */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1179" > < span class = "lineNum" > 1179 < / span > < span class = "lineCov" > 12787 : fs_deallocate(handle[j].disk, blockcur);< / span > < / a >
< a name = "1180" > < span class = "lineNum" > 1180 < / span > < span class = "lineCov" > 12787 : continue;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1181" > < span class = "lineNum" > 1181 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1182" > < span class = "lineNum" > 1182 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1183" > < span class = "lineNum" > 1183 < / span > : /* now all the blocks have the hash and the parity computed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1184" > < span class = "lineNum" > 1184 < / span > < span class = "lineCov" > 645702 : block_state_set(block, BLOCK_STATE_BLK);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1185" > < span class = "lineNum" > 1185 < / span > : }< / a >
< a name = "1186" > < span class = "lineNum" > 1186 < / span > : < / a >
< a name = "1187" > < span class = "lineNum" > 1187 < / span > : /* we update the info block only if we really have updated the parity */< / a >
< a name = "1188" > < span class = "lineNum" > 1188 < / span > : /* because otherwise the time/justsynced info would be misleading as we didn't */< / a >
< a name = "1189" > < span class = "lineNum" > 1189 < / span > : /* wrote the parity at this time */< / a >
< a name = "1190" > < span class = "lineNum" > 1190 < / span > : /* we also update the info block only if no silent error was found */< / a >
< a name = "1191" > < span class = "lineNum" > 1191 < / span > : /* because has no sense to refresh the time for data that we know bad */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1192" > < span class = "lineNum" > 1192 < / span > < span class = "lineCov" > 126053 : if (parity_needs_to_be_updated< / span > < / a >
< a name = "1193" > < span class = "lineNum" > 1193 < / span > < span class = "lineCov" > 125127 : & & !silent_error_on_this_block< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1194" > < span class = "lineNum" > 1194 < / span > : ) {< / a >
< a name = "1195" > < span class = "lineNum" > 1195 < / span > : /* if rehash is needed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1196" > < span class = "lineNum" > 1196 < / span > < span class = "lineCov" > 124276 : if (rehash) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1197" > < span class = "lineNum" > 1197 < / span > : /* store all the new hash already computed */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1198" > < span class = "lineNum" > 1198 < / span > < span class = "lineCov" > 32459 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
< a name = "1199" > < span class = "lineNum" > 1199 < / span > < span class = "lineCov" > 27822 : if (rehandle[j].block)< / span > < / a >
< a name = "1200" > < span class = "lineNum" > 1200 < / span > < span class = "lineCov" > 27200 : memcpy(rehandle[j].block-> hash, rehandle[j].hash, BLOCK_HASH_SIZE);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1201" > < span class = "lineNum" > 1201 < / span > : }< / a >
< a name = "1202" > < span class = "lineNum" > 1202 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1203" > < span class = "lineNum" > 1203 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1204" > < span class = "lineNum" > 1204 < / span > : /* update the time info of the block */< / a >
< a name = "1205" > < span class = "lineNum" > 1205 < / span > : /* we are also clearing any previous bad and rehash flag */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1206" > < span class = "lineNum" > 1206 < / span > < span class = "lineCov" > 124276 : info_set(& state-> infoarr, blockcur, info_make(now, 0, 0, 1));< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1207" > < span class = "lineNum" > 1207 < / span > : }< / a >
< a name = "1208" > < span class = "lineNum" > 1208 < / span > : }< / a >
< a name = "1209" > < span class = "lineNum" > 1209 < / span > : < / a >
< a name = "1210" > < span class = "lineNum" > 1210 < / span > : /* if a silent (even if corrected) or input/output error was found */< / a >
< a name = "1211" > < span class = "lineNum" > 1211 < / span > : /* mark the block as bad to have check/fix to handle it */< / a >
< a name = "1212" > < span class = "lineNum" > 1212 < / span > : /* because our correction is in memory only and not yet written */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1213" > < span class = "lineNum" > 1213 < / span > < span class = "lineCov" > 126072 : if (silent_error_on_this_block || io_error_on_this_block) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1214" > < span class = "lineNum" > 1214 < / span > : /* set the error status keeping the other info */< / a >
2026-02-28 10:26:32 +01:00
< a name = "1215" > < span class = "lineNum" > 1215 < / span > < span class = "lineCov" > 852 : info_set(& state-> infoarr, blockcur, info_set_bad(info));< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1216" > < span class = "lineNum" > 1216 < / span > : }< / a >
< a name = "1217" > < span class = "lineNum" > 1217 < / span > : < / a >
< a name = "1218" > < span class = "lineNum" > 1218 < / span > : /* finally schedule parity write */< / a >
< a name = "1219" > < span class = "lineNum" > 1219 < / span > : /* Note that the calls to io_parity_write() are mandatory */< / a >
< a name = "1220" > < span class = "lineNum" > 1220 < / span > : /* even if the parity doesn't need to be updated */< / a >
< a name = "1221" > < span class = "lineNum" > 1221 < / span > : /* This because we want to keep track of the time usage */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1222" > < span class = "lineNum" > 1222 < / span > < span class = "lineCov" > 126072 : state_usage_misc(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1223" > < span class = "lineNum" > 1223 < / span > : < / a >
< a name = "1224" > < span class = "lineNum" > 1224 < / span > : /* write start */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1225" > < span class = "lineNum" > 1225 < / span > < span class = "lineCov" > 126072 : io_write_preset(& io, blockcur, !parity_going_to_be_updated);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1226" > < span class = "lineNum" > 1226 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1227" > < span class = "lineNum" > 1227 < / span > : /* write the parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1228" > < span class = "lineNum" > 1228 < / span > < span class = "lineCov" > 705324 : for (l = 0; l < state-> level; ++l) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1229" > < span class = "lineNum" > 1229 < / span > : unsigned levcur;< / a >
< a name = "1230" > < span class = "lineNum" > 1230 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "1231" > < span class = "lineNum" > 1231 < / span > < span class = "lineCov" > 579252 : io_parity_write(& io, & levcur, waiting_map, & waiting_mac);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1232" > < span class = "lineNum" > 1232 < / span > : < / a >
< a name = "1233" > < span class = "lineNum" > 1233 < / span > : /* until now is parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1234" > < span class = "lineNum" > 1234 < / span > < span class = "lineCov" > 579252 : state_usage_parity(state, waiting_map, waiting_mac);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1235" > < span class = "lineNum" > 1235 < / span > : }< / a >
< a name = "1236" > < span class = "lineNum" > 1236 < / span > : < / a >
< a name = "1237" > < span class = "lineNum" > 1237 < / span > : /* write finished */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1238" > < span class = "lineNum" > 1238 < / span > < span class = "lineCov" > 126072 : io_write_next(& io, blockcur, !parity_going_to_be_updated, writer_error);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1239" > < span class = "lineNum" > 1239 < / span > : < / a >
< a name = "1240" > < span class = "lineNum" > 1240 < / span > : /* handle errors reported */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1241" > < span class = "lineNum" > 1241 < / span > < span class = "lineCov" > 630360 : for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {< / span > < / a >
< a name = "1242" > < span class = "lineNum" > 1242 < / span > < span class = "lineCov" > 504288 : if (writer_error[j]) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1243" > < span class = "lineNum" > 1243 < / span > < span class = "lineNoCov" > 0 : switch (j + IO_WRITER_ERROR_BASE) {< / span > < / a >
< a name = "1244" > < span class = "lineNum" > 1244 < / span > < span class = "lineNoCov" > 0 : case TASK_STATE_IOERROR_CONTINUE :< / span > < / a >
< a name = "1245" > < span class = "lineNum" > 1245 < / span > < span class = "lineNoCov" > 0 : ++io_error;< / span > < / a >
< a name = "1246" > < span class = "lineNum" > 1246 < / span > < span class = "lineNoCov" > 0 : if (io_error > = state-> opt.io_error_limit) {< / span > < / a >
< a name = "1247" > < span class = "lineNum" > 1247 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1248" > < span class = "lineNum" > 1248 < / span > : log_fatal(EIO, " DANGER! Too many input/output errors in a parity disk. It isn't possible to continue.\n" );< / a >
< a name = "1249" > < span class = "lineNum" > 1249 < / span > : log_fatal(EIO, " Stopping at block %u\n" , blockcur);< / a >
< a name = "1250" > < span class = "lineNum" > 1250 < / span > : goto bail;< / a >
< a name = "1251" > < span class = "lineNum" > 1251 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1252" > < span class = "lineNum" > 1252 < / span > : }< / a >
< a name = "1253" > < span class = "lineNum" > 1253 < / span > < span class = "lineNoCov" > 0 : break;< / span > < / a >
< a name = "1254" > < span class = "lineNum" > 1254 < / span > < span class = "lineNoCov" > 0 : case TASK_STATE_ERROR_CONTINUE :< / span > < / a >
< a name = "1255" > < span class = "lineNum" > 1255 < / span > < span class = "lineNoCov" > 0 : ++soft_error;< / span > < / a >
< a name = "1256" > < span class = "lineNum" > 1256 < / span > < span class = "lineNoCov" > 0 : break;< / span > < / a >
< a name = "1257" > < span class = "lineNum" > 1257 < / span > < span class = "lineNoCov" > 0 : case TASK_STATE_IOERROR :< / span > < / a >
< a name = "1258" > < span class = "lineNum" > 1258 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1259" > < span class = "lineNum" > 1259 < / span > : ++io_error;< / a >
< a name = "1260" > < span class = "lineNum" > 1260 < / span > : goto bail;< / a >
< a name = "1261" > < span class = "lineNum" > 1261 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1262" > < span class = "lineNum" > 1262 < / span > < span class = "lineNoCov" > 0 : case TASK_STATE_ERROR :< / span > < / a >
< a name = "1263" > < span class = "lineNum" > 1263 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1264" > < span class = "lineNum" > 1264 < / span > : ++soft_error;< / a >
< a name = "1265" > < span class = "lineNum" > 1265 < / span > : goto bail;< / a >
< a name = "1266" > < span class = "lineNum" > 1266 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1267" > < span class = "lineNum" > 1267 < / span > : }< / a >
< a name = "1268" > < span class = "lineNum" > 1268 < / span > : }< / a >
< a name = "1269" > < span class = "lineNum" > 1269 < / span > : }< / a >
< a name = "1270" > < span class = "lineNum" > 1270 < / span > : < / a >
< a name = "1271" > < span class = "lineNum" > 1271 < / span > : /* mark the state as needing write */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1272" > < span class = "lineNum" > 1272 < / span > < span class = "lineCov" > 126072 : state-> need_write = 1;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1273" > < span class = "lineNum" > 1273 < / span > : < / a >
< a name = "1274" > < span class = "lineNum" > 1274 < / span > : /* count the number of processed block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1275" > < span class = "lineNum" > 1275 < / span > < span class = "lineCov" > 126072 : ++countpos;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1276" > < span class = "lineNum" > 1276 < / span > : < / a >
< a name = "1277" > < span class = "lineNum" > 1277 < / span > : /* progress */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1278" > < span class = "lineNum" > 1278 < / span > < span class = "lineCov" > 126072 : if (state_progress(state, & io, blockcur, countpos, countmax, countsize)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1279" > < span class = "lineNum" > 1279 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1280" > < span class = "lineNum" > 1280 < / span > : break;< / a >
< a name = "1281" > < span class = "lineNum" > 1281 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1282" > < span class = "lineNum" > 1282 < / span > : }< / a >
< a name = "1283" > < span class = "lineNum" > 1283 < / span > : < / a >
< a name = "1284" > < span class = "lineNum" > 1284 < / span > : /* thermal control */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1285" > < span class = "lineNum" > 1285 < / span > < span class = "lineCov" > 126072 : if (state_thermal_alarm(state)) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1286" > < span class = "lineNum" > 1286 < / span > : /* until now is misc */< / a >
< a name = "1287" > < span class = "lineNum" > 1287 < / span > < span class = "lineNoCov" > 0 : state_usage_misc(state);< / span > < / a >
< a name = "1288" > < span class = "lineNum" > 1288 < / span > : < / a >
< a name = "1289" > < span class = "lineNum" > 1289 < / span > < span class = "lineNoCov" > 0 : state_progress_stop(state);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1290" > < span class = "lineNum" > 1290 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1291" > < span class = "lineNum" > 1291 < / span > : /* before spinning down flush all the caches */< / a >
< a name = "1292" > < span class = "lineNum" > 1292 < / span > < span class = "lineNoCov" > 0 : ret = state_flush(state, & io, parity_handle, blockcur);< / span > < / a >
< a name = "1293" > < span class = "lineNum" > 1293 < / span > < span class = "lineNoCov" > 0 : if (ret == -1) {< / span > < / a >
< a name = "1294" > < span class = "lineNum" > 1294 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1295" > < span class = "lineNum" > 1295 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "1296" > < span class = "lineNum" > 1296 < / span > : ++io_error;< / a >
< a name = "1297" > < span class = "lineNum" > 1297 < / span > : goto bail;< / a >
< a name = "1298" > < span class = "lineNum" > 1298 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1299" > < span class = "lineNum" > 1299 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1300" > < span class = "lineNum" > 1300 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1301" > < span class = "lineNum" > 1301 < / span > < span class = "lineNoCov" > 0 : state_thermal_cooldown(state);< / span > < / a >
< a name = "1302" > < span class = "lineNum" > 1302 < / span > : < / a >
< a name = "1303" > < span class = "lineNum" > 1303 < / span > < span class = "lineNoCov" > 0 : state_progress_restart(state);< / span > < / a >
< a name = "1304" > < span class = "lineNum" > 1304 < / span > : < / a >
< a name = "1305" > < span class = "lineNum" > 1305 < / span > : /* drop until now */< / a >
< a name = "1306" > < span class = "lineNum" > 1306 < / span > < span class = "lineNoCov" > 0 : state_usage_waste(state);< / span > < / a >
< a name = "1307" > < span class = "lineNum" > 1307 < / span > : }< / a >
< a name = "1308" > < span class = "lineNum" > 1308 < / span > : < / a >
< a name = "1309" > < span class = "lineNum" > 1309 < / span > : /* autosave */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1310" > < span class = "lineNum" > 1310 < / span > < span class = "lineCov" > 126072 : if ((state-> autosave != 0< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "1311" > < span class = "lineNum" > 1311 < / span > < span class = "lineCov" > 35436 : & & autosavedone > = autosavelimit /* if we have reached the limit */< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1312" > < span class = "lineNum" > 1312 < / span > < span class = "lineNoCov" > 0 : & & autosavemissing > = autosavelimit) /* if we have at least a full step to do */< / span > < / a >
< a name = "1313" > < span class = "lineNum" > 1313 < / span > : /* or if we have a forced autosave at the specified block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "1314" > < span class = "lineNum" > 1314 < / span > < span class = "lineCov" > 126072 : || (state-> opt.force_autosave_at != 0 & & state-> opt.force_autosave_at == blockcur)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1315" > < span class = "lineNum" > 1315 < / span > : ) {< / a >
< a name = "1316" > < span class = "lineNum" > 1316 < / span > < span class = "lineCov" > 1 : autosavedone = 0; /* restart the counter */< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1317" > < span class = "lineNum" > 1317 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1318" > < span class = "lineNum" > 1318 < / span > : /* until now is misc */< / a >
< a name = "1319" > < span class = "lineNum" > 1319 < / span > < span class = "lineCov" > 1 : state_usage_misc(state);< / span > < / a >
< a name = "1320" > < span class = "lineNum" > 1320 < / span > : < / a >
< a name = "1321" > < span class = "lineNum" > 1321 < / span > < span class = "lineCov" > 1 : state_progress_stop(state);< / span > < / a >
< a name = "1322" > < span class = "lineNum" > 1322 < / span > : < / a >
< a name = "1323" > < span class = "lineNum" > 1323 < / span > < span class = "lineCov" > 1 : msg_progress(" Autosaving...\n" );< / span > < / a >
< a name = "1324" > < span class = "lineNum" > 1324 < / span > : < / a >
< a name = "1325" > < span class = "lineNum" > 1325 < / span > : /* before writing the new content file we ensure that */< / a >
< a name = "1326" > < span class = "lineNum" > 1326 < / span > : /* the parity is really written flushing the disk cache */< / a >
< a name = "1327" > < span class = "lineNum" > 1327 < / span > < span class = "lineCov" > 1 : ret = state_flush(state, & io, parity_handle, blockcur);< / span > < / a >
< a name = "1328" > < span class = "lineNum" > 1328 < / span > < span class = "lineCov" > 1 : if (ret == -1) {< / span > < / a >
< a name = "1329" > < span class = "lineNum" > 1329 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1330" > < span class = "lineNum" > 1330 < / span > : log_fatal(EIO, " Stopping at block %u\n" , blockcur);< / a >
< a name = "1331" > < span class = "lineNum" > 1331 < / span > : ++io_error;< / a >
< a name = "1332" > < span class = "lineNum" > 1332 < / span > : goto bail;< / a >
< a name = "1333" > < span class = "lineNum" > 1333 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1334" > < span class = "lineNum" > 1334 < / span > : }< / a >
< a name = "1335" > < span class = "lineNum" > 1335 < / span > : < / a >
< a name = "1336" > < span class = "lineNum" > 1336 < / span > : /* now we can safely write the content file */< / a >
< a name = "1337" > < span class = "lineNum" > 1337 < / span > < span class = "lineCov" > 1 : state_write(state);< / span > < / a >
< a name = "1338" > < span class = "lineNum" > 1338 < / span > : < / a >
< a name = "1339" > < span class = "lineNum" > 1339 < / span > < span class = "lineCov" > 1 : state_progress_restart(state);< / span > < / a >
< a name = "1340" > < span class = "lineNum" > 1340 < / span > : < / a >
< a name = "1341" > < span class = "lineNum" > 1341 < / span > : /* drop until now */< / a >
< a name = "1342" > < span class = "lineNum" > 1342 < / span > < span class = "lineCov" > 1 : state_usage_waste(state);< / span > < / a >
< a name = "1343" > < span class = "lineNum" > 1343 < / span > : }< / a >
< a name = "1344" > < span class = "lineNum" > 1344 < / span > : }< / a >
< a name = "1345" > < span class = "lineNum" > 1345 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1346" > < span class = "lineNum" > 1346 < / span > < span class = "lineCov" > 92 : end:< / span > < / a >
< a name = "1347" > < span class = "lineNum" > 1347 < / span > < span class = "lineCov" > 92 : state_progress_end(state, countpos, countmax, countsize, " Nothing to sync.\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1348" > < span class = "lineNum" > 1348 < / span > : < / a >
< a name = "1349" > < span class = "lineNum" > 1349 < / span > : /* before returning we ensure that */< / a >
< a name = "1350" > < span class = "lineNum" > 1350 < / span > : /* the parity is really written flushing the disk cache */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1351" > < span class = "lineNum" > 1351 < / span > < span class = "lineCov" > 92 : ret = state_flush(state, & io, parity_handle, blockcur);< / span > < / a >
< a name = "1352" > < span class = "lineNum" > 1352 < / span > < span class = "lineCov" > 92 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1353" > < span class = "lineNum" > 1353 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1354" > < span class = "lineNum" > 1354 < / span > : log_fatal(errno, " Stopping at block %u\n" , blockcur);< / a >
< a name = "1355" > < span class = "lineNum" > 1355 < / span > : ++io_error;< / a >
< a name = "1356" > < span class = "lineNum" > 1356 < / span > : goto bail;< / a >
< a name = "1357" > < span class = "lineNum" > 1357 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1358" > < span class = "lineNum" > 1358 < / span > : }< / a >
< a name = "1359" > < span class = "lineNum" > 1359 < / span > : < / a >
< a name = "1360" > < span class = "lineNum" > 1360 < / span > : /* save the new state if required */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1361" > < span class = "lineNum" > 1361 < / span > < span class = "lineCov" > 92 : if (!state-> opt.kill_after_sync) {< / span > < / a >
< a name = "1362" > < span class = "lineNum" > 1362 < / span > < span class = "lineCov" > 82 : if ((state-> need_write || state-> opt.force_content_write))< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "1363" > < span class = "lineNum" > 1363 < / span > < span class = "lineCov" > 64 : state_write(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1364" > < span class = "lineNum" > 1364 < / span > : } else {< / a >
< a name = "1365" > < span class = "lineNum" > 1365 < / span > < span class = "lineCov" > 10 : log_fatal(EUSER, " WARNING! Skipped writing state due to --test-kill-after-sync option.\n" );< / span > < / a >
< a name = "1366" > < span class = "lineNum" > 1366 < / span > : }< / a >
< a name = "1367" > < span class = "lineNum" > 1367 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1368" > < span class = "lineNum" > 1368 < / span > < span class = "lineCov" > 92 : state_usage_print(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1369" > < span class = "lineNum" > 1369 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1370" > < span class = "lineNum" > 1370 < / span > < span class = "lineCov" > 92 : if (soft_error || silent_error || io_error) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1371" > < span class = "lineNum" > 1371 < / span > < span class = "lineCov" > 12 : msg_status(" \n" );< / span > < / a >
< a name = "1372" > < span class = "lineNum" > 1372 < / span > < span class = "lineCov" > 12 : msg_status(" %8u soft errors\n" , soft_error);< / span > < / a >
< a name = "1373" > < span class = "lineNum" > 1373 < / span > < span class = "lineCov" > 12 : msg_status(" %8u io errors\n" , io_error);< / span > < / a >
< a name = "1374" > < span class = "lineNum" > 1374 < / span > < span class = "lineCov" > 12 : msg_status(" %8u data errors\n" , silent_error);< / span > < / a >
< a name = "1375" > < span class = "lineNum" > 1375 < / span > : } else {< / a >
< a name = "1376" > < span class = "lineNum" > 1376 < / span > : /* print the result only if processed something */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1377" > < span class = "lineNum" > 1377 < / span > < span class = "lineCov" > 80 : if (countpos != 0)< / span > < / a >
2026-03-15 18:52:43 +01:00
< a name = "1378" > < span class = "lineNum" > 1378 < / span > < span class = "lineCov" > 60 : msg_status(" Everything OK\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1379" > < span class = "lineNum" > 1379 < / span > : }< / a >
< a name = "1380" > < span class = "lineNum" > 1380 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1381" > < span class = "lineNum" > 1381 < / span > < span class = "lineCov" > 92 : if (soft_error)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1382" > < span class = "lineNum" > 1382 < / span > < span class = "lineCov" > 11 : log_fatal(ESOFT, " WARNING! Unexpected soft errors!\n" );< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "1383" > < span class = "lineNum" > 1383 < / span > < span class = "lineCov" > 92 : if (io_error)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1384" > < span class = "lineNum" > 1384 < / span > < span class = "lineNoCov" > 0 : log_fatal(EIO, " DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n" );< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "1385" > < span class = "lineNum" > 1385 < / span > < span class = "lineCov" > 92 : if (silent_error)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1386" > < span class = "lineNum" > 1386 < / span > < span class = "lineCov" > 1 : log_fatal(EDATA, " DANGER! Unexpected silent data errors! The failing blocks are now marked as bad!\n" );< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "1387" > < span class = "lineNum" > 1387 < / span > < span class = "lineCov" > 92 : if (io_error || silent_error) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1388" > < span class = "lineNum" > 1388 < / span > < span class = "lineCov" > 1 : log_fatal(ESOFT, " Use 'snapraid status' to list the bad blocks.\n" );< / span > < / a >
< a name = "1389" > < span class = "lineNum" > 1389 < / span > < span class = "lineCov" > 1 : log_fatal(ESOFT, " Use 'snapraid -e fix' to recover.\n" );< / span > < / a >
< a name = "1390" > < span class = "lineNum" > 1390 < / span > : }< / a >
< a name = "1391" > < span class = "lineNum" > 1391 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1392" > < span class = "lineNum" > 1392 < / span > < span class = "lineCov" > 92 : log_tag(" summary:error_soft:%u\n" , soft_error);< / span > < / a >
< a name = "1393" > < span class = "lineNum" > 1393 < / span > < span class = "lineCov" > 92 : log_tag(" summary:error_io:%u\n" , io_error);< / span > < / a >
< a name = "1394" > < span class = "lineNum" > 1394 < / span > < span class = "lineCov" > 92 : log_tag(" summary:error_data:%u\n" , silent_error);< / span > < / a >
< a name = "1395" > < span class = "lineNum" > 1395 < / span > < span class = "lineCov" > 92 : if (soft_error + silent_error + io_error == 0)< / span > < / a >
< a name = "1396" > < span class = "lineNum" > 1396 < / span > < span class = "lineCov" > 80 : log_tag(" summary:exit:ok\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1397" > < span class = "lineNum" > 1397 < / span > < span class = "lineCov" > 12 : else if (silent_error + io_error == 0)< / span > < / a >
< a name = "1398" > < span class = "lineNum" > 1398 < / span > < span class = "lineCov" > 11 : log_tag(" summary:exit:warning\n" );< / span > < / a >
< a name = "1399" > < span class = "lineNum" > 1399 < / span > : else< / a >
< a name = "1400" > < span class = "lineNum" > 1400 < / span > < span class = "lineCov" > 1 : log_tag(" summary:exit:error\n" );< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "1401" > < span class = "lineNum" > 1401 < / span > < span class = "lineCov" > 92 : log_flush();< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1402" > < span class = "lineNum" > 1402 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1403" > < span class = "lineNum" > 1403 < / span > < span class = "lineCov" > 92 : bail:< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1404" > < span class = "lineNum" > 1404 < / span > : /* stop all the worker threads */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1405" > < span class = "lineNum" > 1405 < / span > < span class = "lineCov" > 92 : io_stop(& io);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1406" > < span class = "lineNum" > 1406 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1407" > < span class = "lineNum" > 1407 < / span > < span class = "lineCov" > 644 : for (j = 0; j < diskmax; ++j) {< / span > < / a >
< a name = "1408" > < span class = "lineNum" > 1408 < / span > < span class = "lineCov" > 552 : struct snapraid_file* file = handle[j].file;< / span > < / a >
< a name = "1409" > < span class = "lineNum" > 1409 < / span > < span class = "lineCov" > 552 : struct snapraid_disk* disk = handle[j].disk;< / span > < / a >
< a name = "1410" > < span class = "lineNum" > 1410 < / span > < span class = "lineCov" > 552 : ret = handle_close(& handle[j]);< / span > < / a >
< a name = "1411" > < span class = "lineNum" > 1411 < / span > < span class = "lineCov" > 552 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1412" > < span class = "lineNum" > 1412 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1413" > < span class = "lineNum" > 1413 < / span > : log_tag(" %s:%u:%s:%s: Close error. %s.\n" , es(errno), blockcur, disk-> name, esc_tag(file-> sub, esc_buffer), strerror(errno));< / a >
< a name = "1414" > < span class = "lineNum" > 1414 < / span > : log_fatal_errno(errno, disk-> name);< / a >
< a name = "1415" > < span class = "lineNum" > 1415 < / span > : < / a >
< a name = "1416" > < span class = "lineNum" > 1416 < / span > : if (is_hw(errno)) {< / a >
< a name = "1417" > < span class = "lineNum" > 1417 < / span > : ++io_error;< / a >
< a name = "1418" > < span class = "lineNum" > 1418 < / span > : } else {< / a >
< a name = "1419" > < span class = "lineNum" > 1419 < / span > : ++soft_error;< / a >
< a name = "1420" > < span class = "lineNum" > 1420 < / span > : }< / a >
< a name = "1421" > < span class = "lineNum" > 1421 < / span > : /* continue, as we are already exiting */< / a >
< a name = "1422" > < span class = "lineNum" > 1422 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1423" > < span class = "lineNum" > 1423 < / span > : }< / a >
< a name = "1424" > < span class = "lineNum" > 1424 < / span > : }< / a >
< a name = "1425" > < span class = "lineNum" > 1425 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1426" > < span class = "lineNum" > 1426 < / span > < span class = "lineCov" > 92 : free(handle);< / span > < / a >
< a name = "1427" > < span class = "lineNum" > 1427 < / span > < span class = "lineCov" > 92 : free(zero_alloc);< / span > < / a >
< a name = "1428" > < span class = "lineNum" > 1428 < / span > < span class = "lineCov" > 92 : free(copy_alloc);< / span > < / a >
< a name = "1429" > < span class = "lineNum" > 1429 < / span > < span class = "lineCov" > 92 : free(copy);< / span > < / a >
< a name = "1430" > < span class = "lineNum" > 1430 < / span > < span class = "lineCov" > 92 : free(rehandle_alloc);< / span > < / a >
< a name = "1431" > < span class = "lineNum" > 1431 < / span > < span class = "lineCov" > 92 : free(failed);< / span > < / a >
< a name = "1432" > < span class = "lineNum" > 1432 < / span > < span class = "lineCov" > 92 : free(failed_map);< / span > < / a >
< a name = "1433" > < span class = "lineNum" > 1433 < / span > < span class = "lineCov" > 92 : free(waiting_map);< / span > < / a >
< a name = "1434" > < span class = "lineNum" > 1434 < / span > < span class = "lineCov" > 92 : io_done(& io);< / span > < / a >
< a name = "1435" > < span class = "lineNum" > 1435 < / span > < span class = "lineCov" > 92 : free(block_enabled);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1436" > < span class = "lineNum" > 1436 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1437" > < span class = "lineNum" > 1437 < / span > < span class = "lineCov" > 92 : if (state-> opt.expect_recoverable) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1438" > < span class = "lineNum" > 1438 < / span > < span class = "lineCov" > 1 : if (soft_error + silent_error + io_error == 0)< / span > < / a >
< a name = "1439" > < span class = "lineNum" > 1439 < / span > < span class = "lineNoCov" > 0 : return -1;< / span > < / a >
< a name = "1440" > < span class = "lineNum" > 1440 < / span > : } else {< / a >
2026-02-28 16:47:55 +01:00
< a name = "1441" > < span class = "lineNum" > 1441 < / span > < span class = "lineCov" > 91 : if (soft_error + silent_error + io_error != 0)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1442" > < span class = "lineNum" > 1442 < / span > < span class = "lineCov" > 11 : return -1;< / span > < / a >
< a name = "1443" > < span class = "lineNum" > 1443 < / span > : }< / a >
< a name = "1444" > < span class = "lineNum" > 1444 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1445" > < span class = "lineNum" > 1445 < / span > < span class = "lineCov" > 81 : if (alert < 0)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1446" > < span class = "lineNum" > 1446 < / span > < span class = "lineNoCov" > 0 : return -1;< / span > < / a >
< a name = "1447" > < span class = "lineNum" > 1447 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1448" > < span class = "lineNum" > 1448 < / span > < span class = "lineCov" > 81 : return 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1449" > < span class = "lineNum" > 1449 < / span > : }< / a >
< a name = "1450" > < span class = "lineNum" > 1450 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1451" > < span class = "lineNum" > 1451 < / span > < span class = "lineCov" > 96 : int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1452" > < span class = "lineNum" > 1452 < / span > : {< / a >
< a name = "1453" > < span class = "lineNum" > 1453 < / span > : block_off_t blockmax;< / a >
< a name = "1454" > < span class = "lineNum" > 1454 < / span > : block_off_t used_paritymax;< / a >
< a name = "1455" > < span class = "lineNum" > 1455 < / span > : block_off_t file_paritymax;< / a >
< a name = "1456" > < span class = "lineNum" > 1456 < / span > : data_off_t size;< / a >
< a name = "1457" > < span class = "lineNum" > 1457 < / span > : int ret;< / a >
< a name = "1458" > < span class = "lineNum" > 1458 < / span > : struct snapraid_parity_handle parity_handle[LEV_MAX];< / a >
< a name = "1459" > < span class = "lineNum" > 1459 < / span > : unsigned process_error;< / a >
< a name = "1460" > < span class = "lineNum" > 1460 < / span > : unsigned l;< / a >
2026-02-28 16:47:55 +01:00
< a name = "1461" > < span class = "lineNum" > 1461 < / span > < span class = "lineCov" > 96 : int skip_sync = 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1462" > < span class = "lineNum" > 1462 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1463" > < span class = "lineNum" > 1463 < / span > < span class = "lineCov" > 96 : msg_progress(" Initializing...\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1464" > < span class = "lineNum" > 1464 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1465" > < span class = "lineNum" > 1465 < / span > < span class = "lineCov" > 96 : blockmax = parity_allocated_size(state);< / span > < / a >
< a name = "1466" > < span class = "lineNum" > 1466 < / span > < span class = "lineCov" > 96 : size = blockmax * (data_off_t)state-> block_size;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1467" > < span class = "lineNum" > 1467 < / span > : < / a >
< a name = "1468" > < span class = "lineNum" > 1468 < / span > : /* minimum size of the parity files we expect */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1469" > < span class = "lineNum" > 1469 < / span > < span class = "lineCov" > 96 : used_paritymax = parity_used_size(state);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1470" > < span class = "lineNum" > 1470 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1471" > < span class = "lineNum" > 1471 < / span > : /* effective size of the parity files */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1472" > < span class = "lineNum" > 1472 < / span > < span class = "lineCov" > 96 : file_paritymax = 0;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1473" > < span class = "lineNum" > 1473 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1474" > < span class = "lineNum" > 1474 < / span > < span class = "lineCov" > 96 : if (blockstart > blockmax) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1475" > < span class = "lineNum" > 1475 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1476" > < span class = "lineNum" > 1476 < / span > : log_fatal(EUSER, " Error in the starting block %u. It is larger than the parity size %u.\n" , blockstart, blockmax);< / a >
< a name = "1477" > < span class = "lineNum" > 1477 < / span > : exit(EXIT_FAILURE);< / a >
< a name = "1478" > < span class = "lineNum" > 1478 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1479" > < span class = "lineNum" > 1479 < / span > : }< / a >
< a name = "1480" > < span class = "lineNum" > 1480 < / span > : < / a >
< a name = "1481" > < span class = "lineNum" > 1481 < / span > : /* adjust the number of block to process */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1482" > < span class = "lineNum" > 1482 < / span > < span class = "lineCov" > 96 : if (blockcount != 0 & & blockstart + blockcount < blockmax) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1483" > < span class = "lineNum" > 1483 < / span > < span class = "lineCov" > 6 : blockmax = blockstart + blockcount;< / span > < / a >
< a name = "1484" > < span class = "lineNum" > 1484 < / span > : }< / a >
< a name = "1485" > < span class = "lineNum" > 1485 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1486" > < span class = "lineNum" > 1486 < / span > < span class = "lineCov" > 627 : for (l = 0; l < state-> level; ++l) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1487" > < span class = "lineNum" > 1487 < / span > : data_off_t out_size;< / a >
< a name = "1488" > < span class = "lineNum" > 1488 < / span > : block_off_t parityblocks;< / a >
< a name = "1489" > < span class = "lineNum" > 1489 < / span > : < / a >
< a name = "1490" > < span class = "lineNum" > 1490 < / span > : /* create the file and open for writing */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1491" > < span class = "lineNum" > 1491 < / span > < span class = "lineCov" > 531 : ret = parity_create(& parity_handle[l], & state-> parity[l], l, state-> file_mode, state-> block_size, state-> opt.parity_limit_size);< / span > < / a >
< a name = "1492" > < span class = "lineNum" > 1492 < / span > < span class = "lineCov" > 531 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1493" > < span class = "lineNum" > 1493 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1494" > < span class = "lineNum" > 1494 < / span > : log_tag(" parity_%s:%u:%s: Create error. %s.\n" , es(errno), 0, lev_config_name(l), strerror(errno));< / a >
< a name = "1495" > < span class = "lineNum" > 1495 < / span > : log_fatal_errno(errno, lev_config_name(l));< / a >
< a name = "1496" > < span class = "lineNum" > 1496 < / span > : exit(EXIT_FAILURE);< / a >
< a name = "1497" > < span class = "lineNum" > 1497 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1498" > < span class = "lineNum" > 1498 < / span > : }< / a >
< a name = "1499" > < span class = "lineNum" > 1499 < / span > : < / a >
< a name = "1500" > < span class = "lineNum" > 1500 < / span > : /* number of block in the parity file */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1501" > < span class = "lineNum" > 1501 < / span > < span class = "lineCov" > 531 : parity_size(& parity_handle[l], & out_size);< / span > < / a >
< a name = "1502" > < span class = "lineNum" > 1502 < / span > < span class = "lineCov" > 531 : parityblocks = out_size / state-> block_size;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1503" > < span class = "lineNum" > 1503 < / span > : < / a >
< a name = "1504" > < span class = "lineNum" > 1504 < / span > : /* if the file is too small */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1505" > < span class = "lineNum" > 1505 < / span > < span class = "lineCov" > 531 : if (parityblocks < used_paritymax) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1506" > < span class = "lineNum" > 1506 < / span > < span class = "lineNoCov" > 0 : log_fatal(ESOFT, " WARNING! The %s parity has only %u blocks instead of %u.\n" , lev_name(l), parityblocks, used_paritymax);< / span > < / a >
< a name = "1507" > < span class = "lineNum" > 1507 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1508" > < span class = "lineNum" > 1508 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1509" > < span class = "lineNum" > 1509 < / span > : /* keep the smallest parity number of blocks */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1510" > < span class = "lineNum" > 1510 < / span > < span class = "lineCov" > 531 : if (l == 0 || file_paritymax > parityblocks)< / span > < / a >
< a name = "1511" > < span class = "lineNum" > 1511 < / span > < span class = "lineCov" > 97 : file_paritymax = parityblocks;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1512" > < span class = "lineNum" > 1512 < / span > : }< / a >
2025-10-28 12:01:21 +01:00
< a name = "1513" > < span class = "lineNum" > 1513 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1514" > < span class = "lineNum" > 1514 < / span > : /* if we do a full parity realloc or computation, having a wrong parity size is expected */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1515" > < span class = "lineNum" > 1515 < / span > < span class = "lineCov" > 96 : if (!state-> opt.force_realloc & & !state-> opt.force_full) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1516" > < span class = "lineNum" > 1516 < / span > : /* if the parities are too small */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1517" > < span class = "lineNum" > 1517 < / span > < span class = "lineCov" > 86 : if (file_paritymax < used_paritymax) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1518" > < span class = "lineNum" > 1518 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1519" > < span class = "lineNum" > 1519 < / span > : log_fatal(ESOFT, " DANGER! One or more the parity files are smaller than expected!\n" );< / a >
< a name = "1520" > < span class = "lineNum" > 1520 < / span > : if (file_paritymax != 0) {< / a >
< a name = "1521" > < span class = "lineNum" > 1521 < / span > : log_fatal(ESOFT, " If this happens because you are using an old content file,\n" );< / a >
< a name = "1522" > < span class = "lineNum" > 1522 < / span > : log_fatal(ESOFT, " you can 'sync' anyway using 'snapraid --force-full sync'\n" );< / a >
< a name = "1523" > < span class = "lineNum" > 1523 < / span > : log_fatal(ESOFT, " to force a full rebuild of the parity.\n" );< / a >
< a name = "1524" > < span class = "lineNum" > 1524 < / span > : } else {< / a >
< a name = "1525" > < span class = "lineNum" > 1525 < / span > : log_fatal(ESOFT, " It's possible that the parity disks are not mounted.\n" );< / a >
< a name = "1526" > < span class = "lineNum" > 1526 < / span > : log_fatal(ESOFT, " If instead you are adding a new parity level, you can 'sync' using\n" );< / a >
< a name = "1527" > < span class = "lineNum" > 1527 < / span > : log_fatal(ESOFT, " 'snapraid --force-full sync' to force a full rebuild of the parity.\n" );< / a >
< a name = "1528" > < span class = "lineNum" > 1528 < / span > : }< / a >
< a name = "1529" > < span class = "lineNum" > 1529 < / span > : exit(EXIT_FAILURE);< / a >
< a name = "1530" > < span class = "lineNum" > 1530 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1531" > < span class = "lineNum" > 1531 < / span > : }< / a >
< a name = "1532" > < span class = "lineNum" > 1532 < / span > : }< / a >
< a name = "1533" > < span class = "lineNum" > 1533 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1534" > < span class = "lineNum" > 1534 < / span > < span class = "lineCov" > 96 : process_error = 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1535" > < span class = "lineNum" > 1535 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1536" > < span class = "lineNum" > 1536 < / span > < span class = "lineCov" > 96 : if (state-> opt.prehash) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1537" > < span class = "lineNum" > 1537 < / span > < span class = "lineCov" > 7 : msg_progress(" Hashing...\n" );< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "1538" > < span class = "lineNum" > 1538 < / span > : < / a >
2026-02-28 09:59:35 +01:00
< a name = "1539" > < span class = "lineNum" > 1539 < / span > < span class = "lineCov" > 7 : ret = state_hash_process(state, blockstart, blockmax, & skip_sync);< / span > < / a >
< a name = "1540" > < span class = "lineNum" > 1540 < / span > < span class = "lineCov" > 7 : if (ret == -1) {< / span > < / a >
< a name = "1541" > < span class = "lineNum" > 1541 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1542" > < span class = "lineNum" > 1542 < / span > : ++process_error;< / a >
< a name = "1543" > < span class = "lineNum" > 1543 < / span > : /* continue, in case also doing the sync if ::skip_sync is not set */< / a >
< a name = "1544" > < span class = "lineNum" > 1544 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1545" > < span class = "lineNum" > 1545 < / span > : }< / a >
< a name = "1546" > < span class = "lineNum" > 1546 < / span > : }< / a >
< a name = "1547" > < span class = "lineNum" > 1547 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1548" > < span class = "lineNum" > 1548 < / span > < span class = "lineCov" > 96 : if (!skip_sync) {< / span > < / a >
< a name = "1549" > < span class = "lineNum" > 1549 < / span > < span class = "lineCov" > 95 : msg_progress(" Resizing...\n" );< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1550" > < span class = "lineNum" > 1550 < / span > : < / a >
< a name = "1551" > < span class = "lineNum" > 1551 < / span > : /* now change the size of all parities */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1552" > < span class = "lineNum" > 1552 < / span > < span class = "lineCov" > 620 : for (l = 0; l < state-> level; ++l) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1553" > < span class = "lineNum" > 1553 < / span > : int is_modified;< / a >
< a name = "1554" > < span class = "lineNum" > 1554 < / span > : < / a >
< a name = "1555" > < span class = "lineNum" > 1555 < / span > : /* change the size of the parity file, truncating or extending it */< / a >
< a name = "1556" > < span class = "lineNum" > 1556 < / span > : /* from this point all the DELETED blocks after the end of the parity are invalid */< / a >
< a name = "1557" > < span class = "lineNum" > 1557 < / span > : /* and they are automatically removed when we save the new content file */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1558" > < span class = "lineNum" > 1558 < / span > < span class = "lineCov" > 525 : ret = parity_chsize(& parity_handle[l], & state-> parity[l], & is_modified, size, state-> block_size, state-> opt.skip_fallocate, state-> opt.skip_space_holder);< / span > < / a >
< a name = "1559" > < span class = "lineNum" > 1559 < / span > < span class = "lineCov" > 525 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1560" > < span class = "lineNum" > 1560 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1561" > < span class = "lineNum" > 1561 < / span > : data_off_t out_size;< / a >
< a name = "1562" > < span class = "lineNum" > 1562 < / span > : parity_size(& parity_handle[l], & out_size);< / a >
< a name = "1563" > < span class = "lineNum" > 1563 < / span > : parity_overflow(state, out_size);< / a >
< a name = "1564" > < span class = "lineNum" > 1564 < / span > : log_fatal(errno, " WARNING! Without a usable %s file, it isn't possible to sync.\n" , lev_name(l));< / a >
< a name = "1565" > < span class = "lineNum" > 1565 < / span > : exit(EXIT_FAILURE);< / a >
< a name = "1566" > < span class = "lineNum" > 1566 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1567" > < span class = "lineNum" > 1567 < / span > : }< / a >
< a name = "1568" > < span class = "lineNum" > 1568 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1569" > < span class = "lineNum" > 1569 < / span > < span class = "lineCov" > 525 : if (is_modified)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1570" > < span class = "lineNum" > 1570 < / span > < span class = "lineCov" > 199 : state-> need_write = 1;< / span > < / a >
< a name = "1571" > < span class = "lineNum" > 1571 < / span > : }< / a >
< a name = "1572" > < span class = "lineNum" > 1572 < / span > : < / a >
< a name = "1573" > < span class = "lineNum" > 1573 < / span > : /* after resizing parity files, refresh again the free info */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1574" > < span class = "lineNum" > 1574 < / span > < span class = "lineCov" > 95 : state_refresh(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1575" > < span class = "lineNum" > 1575 < / span > : < / a >
< a name = "1576" > < span class = "lineNum" > 1576 < / span > : /**< / a >
< a name = "1577" > < span class = "lineNum" > 1577 < / span > : * Save the new state before the sync but after the hashing phase< / a >
< a name = "1578" > < span class = "lineNum" > 1578 < / span > : *< / a >
< a name = "1579" > < span class = "lineNum" > 1579 < / span > : * This allows to recover after an aborted sync, and at the same time< / a >
< a name = "1580" > < span class = "lineNum" > 1580 < / span > : * it allows to recover broken copied/moved files identified in the< / a >
< a name = "1581" > < span class = "lineNum" > 1581 < / span > : * hashing phase.< / a >
< a name = "1582" > < span class = "lineNum" > 1582 < / span > : *< / a >
< a name = "1583" > < span class = "lineNum" > 1583 < / span > : * For example, think at this case:< / a >
< a name = "1584" > < span class = "lineNum" > 1584 < / span > : * - Add some files at the array< / a >
< a name = "1585" > < span class = "lineNum" > 1585 < / span > : * - Run a sync command, it will recompute the parity adding the new files< / a >
< a name = "1586" > < span class = "lineNum" > 1586 < / span > : * - Abort the sync command before it stores the new content file< / a >
< a name = "1587" > < span class = "lineNum" > 1587 < / span > : * - Delete the not yet synced files from the array< / a >
< a name = "1588" > < span class = "lineNum" > 1588 < / span > : * - Run a new sync command< / a >
< a name = "1589" > < span class = "lineNum" > 1589 < / span > : *< / a >
< a name = "1590" > < span class = "lineNum" > 1590 < / span > : * The sync command has no way to know that the parity file was modified< / a >
< a name = "1591" > < span class = "lineNum" > 1591 < / span > : * because the files triggering these changes are now deleted and they aren't< / a >
< a name = "1592" > < span class = "lineNum" > 1592 < / span > : * listed in the content file.< / a >
< a name = "1593" > < span class = "lineNum" > 1593 < / span > : * Instead, saving the new content file in advance, keeps track of all the parity< / a >
< a name = "1594" > < span class = "lineNum" > 1594 < / span > : * that may be modified.< / a >
< a name = "1595" > < span class = "lineNum" > 1595 < / span > : */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1596" > < span class = "lineNum" > 1596 < / span > < span class = "lineCov" > 95 : if (!state-> opt.skip_content_write) {< / span > < / a >
< a name = "1597" > < span class = "lineNum" > 1597 < / span > < span class = "lineCov" > 95 : if (state-> need_write)< / span > < / a >
< a name = "1598" > < span class = "lineNum" > 1598 < / span > < span class = "lineCov" > 84 : state_write(state);< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1599" > < span class = "lineNum" > 1599 < / span > : } else {< / a >
< a name = "1600" > < span class = "lineNum" > 1600 < / span > < span class = "lineNoCov" > 0 : log_fatal(EUSER, " WARNING! Skipped state write for --test-skip-content-write option.\n" );< / span > < / a >
< a name = "1601" > < span class = "lineNum" > 1601 < / span > : }< / a >
< a name = "1602" > < span class = "lineNum" > 1602 < / span > : < / a >
< a name = "1603" > < span class = "lineNum" > 1603 < / span > : /* skip degenerated cases of empty parity, or skipping all */< / a >
2026-02-28 16:47:55 +01:00
< a name = "1604" > < span class = "lineNum" > 1604 < / span > < span class = "lineCov" > 95 : if (blockstart < blockmax) {< / span > < / a >
< a name = "1605" > < span class = "lineNum" > 1605 < / span > < span class = "lineCov" > 92 : ret = state_sync_process(state, parity_handle, blockstart, blockmax);< / span > < / a >
< a name = "1606" > < span class = "lineNum" > 1606 < / span > < span class = "lineCov" > 92 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1607" > < span class = "lineNum" > 1607 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1608" > < span class = "lineNum" > 1608 < / span > : ++process_error;< / a >
< a name = "1609" > < span class = "lineNum" > 1609 < / span > : /* continue, as we are already exiting */< / a >
< a name = "1610" > < span class = "lineNum" > 1610 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1611" > < span class = "lineNum" > 1611 < / span > : }< / a >
< a name = "1612" > < span class = "lineNum" > 1612 < / span > : } else {< / a >
< a name = "1613" > < span class = "lineNum" > 1613 < / span > < span class = "lineCov" > 3 : msg_status(" Nothing to sync.\n" );< / span > < / a >
< a name = "1614" > < span class = "lineNum" > 1614 < / span > : }< / a >
< a name = "1615" > < span class = "lineNum" > 1615 < / span > : }< / a >
< a name = "1616" > < span class = "lineNum" > 1616 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1617" > < span class = "lineNum" > 1617 < / span > < span class = "lineCov" > 627 : for (l = 0; l < state-> level; ++l) {< / span > < / a >
< a name = "1618" > < span class = "lineNum" > 1618 < / span > < span class = "lineCov" > 531 : ret = parity_close(& parity_handle[l]);< / span > < / a >
< a name = "1619" > < span class = "lineNum" > 1619 < / span > < span class = "lineCov" > 531 : if (ret == -1) {< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1620" > < span class = "lineNum" > 1620 < / span > : /* LCOV_EXCL_START */< / a >
< a name = "1621" > < span class = "lineNum" > 1621 < / span > : log_tag(" parity_%s:%u:%s: Close error. %s.\n" , es(errno), blockmax, lev_config_name(l), strerror(errno));< / a >
< a name = "1622" > < span class = "lineNum" > 1622 < / span > : log_fatal_errno(errno, lev_config_name(l));< / a >
< a name = "1623" > < span class = "lineNum" > 1623 < / span > : < / a >
< a name = "1624" > < span class = "lineNum" > 1624 < / span > : ++process_error;< / a >
< a name = "1625" > < span class = "lineNum" > 1625 < / span > : /* continue, as we are already exiting */< / a >
< a name = "1626" > < span class = "lineNum" > 1626 < / span > : /* LCOV_EXCL_STOP */< / a >
< a name = "1627" > < span class = "lineNum" > 1627 < / span > : }< / a >
< a name = "1628" > < span class = "lineNum" > 1628 < / span > : }< / a >
< a name = "1629" > < span class = "lineNum" > 1629 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "1630" > < span class = "lineNum" > 1630 < / span > < span class = "lineCov" > 96 : if (process_error != 0)< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1631" > < span class = "lineNum" > 1631 < / span > < span class = "lineCov" > 12 : return -1;< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "1632" > < span class = "lineNum" > 1632 < / span > < span class = "lineCov" > 84 : return 0;< / span > < / a >
2026-02-28 09:59:35 +01:00
< a name = "1633" > < span class = "lineNum" > 1633 < / span > : }< / a >
< a name = "1634" > < span class = "lineNum" > 1634 < / span > : < / a >
2011-03-01 22:19:30 +01:00
< / pre >
< / td >
< / tr >
< / table >
< br >
< table width = "100%" border = 0 cellspacing = 0 cellpadding = 0 >
< tr > < td class = "ruler" > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
2025-10-28 12:01:21 +01:00
< tr > < td class = "versionInfo" > Generated by: < a href = "https://github.com/linux-test-project/lcov" target = "_parent" > LCOV version 1.0< / a > < / td > < / tr >
2011-03-01 22:19:30 +01:00
< / table >
< br >
< / body >
< / html >