fx_fault_tolerant_apply_logs.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************************************************** | ||
| 2 | * Copyright (c) 2024 Microsoft Corporation | ||
| 3 | * Copyright (c) 2026-present Eclipse ThreadX contributors | ||
| 4 | * | ||
| 5 | * This program and the accompanying materials are made available under the | ||
| 6 | * terms of the MIT License which is available at | ||
| 7 | * https://opensource.org/licenses/MIT. | ||
| 8 | * | ||
| 9 | * SPDX-License-Identifier: MIT | ||
| 10 | **************************************************************************/ | ||
| 11 | |||
| 12 | // Portions of this file were generated with AI assistance. | ||
| 13 | |||
| 14 | |||
| 15 | /**************************************************************************/ | ||
| 16 | /**************************************************************************/ | ||
| 17 | /** */ | ||
| 18 | /** FileX Component */ | ||
| 19 | /** */ | ||
| 20 | /** Fault Tolerant */ | ||
| 21 | /** */ | ||
| 22 | /**************************************************************************/ | ||
| 23 | /**************************************************************************/ | ||
| 24 | |||
| 25 | #define FX_SOURCE_CODE | ||
| 26 | |||
| 27 | #include "fx_api.h" | ||
| 28 | #include "fx_utility.h" | ||
| 29 | #include "fx_fault_tolerant.h" | ||
| 30 | |||
| 31 | |||
| 32 | #ifdef FX_ENABLE_FAULT_TOLERANT | ||
| 33 | /**************************************************************************/ | ||
| 34 | /* */ | ||
| 35 | /* FUNCTION RELEASE */ | ||
| 36 | /* */ | ||
| 37 | /* _fx_fault_tolerant_apply_logs PORTABLE C */ | ||
| 38 | /* 6.2.0 */ | ||
| 39 | /* AUTHOR */ | ||
| 40 | /* */ | ||
| 41 | /* William E. Lamie, Microsoft Corporation */ | ||
| 42 | /* */ | ||
| 43 | /* DESCRIPTION */ | ||
| 44 | /* */ | ||
| 45 | /* This function applies changes to the file system. The changes are */ | ||
| 46 | /* already recorded in the fault tolerant log file. Therefore this */ | ||
| 47 | /* function reads the content of the log entries and apply these */ | ||
| 48 | /* changes to the file system. */ | ||
| 49 | /* */ | ||
| 50 | /* INPUT */ | ||
| 51 | /* */ | ||
| 52 | /* media_ptr Media control block pointer */ | ||
| 53 | /* */ | ||
| 54 | /* OUTPUT */ | ||
| 55 | /* */ | ||
| 56 | /* return status */ | ||
| 57 | /* */ | ||
| 58 | /* CALLS */ | ||
| 59 | /* */ | ||
| 60 | /* _fx_utility_logical_sector_write Write a logical sector */ | ||
| 61 | /* _fx_utility_logical_sector_read Read a logical sector */ | ||
| 62 | /* _fx_utility_16_unsigned_read Read a USHORT from memory */ | ||
| 63 | /* _fx_utility_32_unsigned_read Read a ULONG from memory */ | ||
| 64 | /* _fx_utility_64_unsigned_read Read a ULONG64 from memory */ | ||
| 65 | /* _fx_utility_FAT_entry_write Write a FAT entry */ | ||
| 66 | /* _fx_fault_tolerant_cleanup_FAT_chain Cleanup FAT chain */ | ||
| 67 | /* memcpy Memory Copy */ | ||
| 68 | /* _fx_utility_FAT_flush Flush written FAT entries */ | ||
| 69 | /* _fx_utility_logical_sector_flush Flush written logical sectors */ | ||
| 70 | /* */ | ||
| 71 | /* CALLED BY */ | ||
| 72 | /* */ | ||
| 73 | /* _fx_fault_tolerant_enable */ | ||
| 74 | /* _fx_fault_tolerant_transaction_end */ | ||
| 75 | /* */ | ||
| 76 | /**************************************************************************/ | ||
| 77 | 160144008 | UINT _fx_fault_tolerant_apply_logs(FX_MEDIA *media_ptr) | |
| 78 | { | ||
| 79 | UINT status; | ||
| 80 | ULONG64 log_sector; | ||
| 81 | ULONG remaining_logs; | ||
| 82 | ULONG copy_size; | ||
| 83 | ULONG copy_offset; | ||
| 84 | UCHAR *current_ptr; | ||
| 85 | ULONG size; | ||
| 86 | USHORT log_type; | ||
| 87 | ULONG log_len; | ||
| 88 | FX_FAULT_TOLERANT_LOG_HEADER *log_header; | ||
| 89 | FX_FAULT_TOLERANT_FAT_CHAIN *FAT_chain; | ||
| 90 | FX_FAULT_TOLERANT_LOG_CONTENT *log_content; | ||
| 91 | FX_FAULT_TOLERANT_FAT_LOG *fat_log; | ||
| 92 | FX_FAULT_TOLERANT_DIR_LOG *dir_log; | ||
| 93 | |||
| 94 | /* Set log header, FAT chain and log content pointer. */ | ||
| 95 | 160144008 | log_header = (FX_FAULT_TOLERANT_LOG_HEADER *)media_ptr -> fx_media_fault_tolerant_memory_buffer; | |
| 96 | 160144008 | FAT_chain = (FX_FAULT_TOLERANT_FAT_CHAIN *)(media_ptr -> fx_media_fault_tolerant_memory_buffer + FX_FAULT_TOLERANT_FAT_CHAIN_OFFSET); | |
| 97 | 160144008 | log_content = (FX_FAULT_TOLERANT_LOG_CONTENT *)(media_ptr -> fx_media_fault_tolerant_memory_buffer + | |
| 98 | FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET); | ||
| 99 | |||
| 100 | /* Find the size of the log file. */ | ||
| 101 | 160144008 | size = _fx_utility_16_unsigned_read((UCHAR *)&log_header -> fx_fault_tolerant_log_header_total_size); | |
| 102 | |||
| 103 | /* Extended port-specific processing macro, which is by default defined to white space. */ | ||
| 104 | 160144008 | FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION | |
| 105 | |||
| 106 | /* The log entries start after the header, the FAT chain and the content header, | ||
| 107 | so only the bytes past all three are available to them. */ | ||
| 108 |
2/2✓ Branch 4 → 5 taken 4 times.
✓ Branch 4 → 6 taken 160144004 times.
|
160144008 | if (size < (FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET + FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE)) |
| 109 | { | ||
| 110 | |||
| 111 | /* Something wrong with log file. */ | ||
| 112 | 4 | return(FX_FILE_CORRUPT); | |
| 113 | } | ||
| 114 | |||
| 115 | 160144004 | size -= (FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET + FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE); | |
| 116 | |||
| 117 | /* Find the number of log entries. */ | ||
| 118 | 160144004 | remaining_logs = _fx_utility_16_unsigned_read((UCHAR *)&log_content -> fx_fault_tolerant_log_content_count); | |
| 119 | |||
| 120 | /* Get start address of logs. */ | ||
| 121 | 160144004 | current_ptr = (UCHAR *)log_content + FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE; | |
| 122 | |||
| 123 | /* Loop through all the logs to apply the changes. */ | ||
| 124 |
2/2✓ Branch 36 → 8 taken 163563061 times.
✓ Branch 36 → 37 taken 160143608 times.
|
323706669 | while (remaining_logs) |
| 125 | { | ||
| 126 | |||
| 127 | /* Obtain log type of this entry. */ | ||
| 128 | 163563061 | log_type = (USHORT)_fx_utility_16_unsigned_read(current_ptr); | |
| 129 | |||
| 130 | /* Read log length. */ | ||
| 131 | 163563061 | log_len = _fx_utility_16_unsigned_read(current_ptr + 2); | |
| 132 | |||
| 133 | |||
| 134 | /* Validate log entry size. */ | ||
| 135 |
4/4✓ Branch 10 → 11 taken 4096 times.
✓ Branch 10 → 12 taken 163558965 times.
✓ Branch 11 → 12 taken 4092 times.
✓ Branch 11 → 15 taken 4 times.
|
163563061 | if (((log_type == FX_FAULT_TOLERANT_FAT_LOG_TYPE) && |
| 136 |
2/2✓ Branch 12 → 13 taken 163558961 times.
✓ Branch 12 → 14 taken 4096 times.
|
163563057 | (log_len < FX_FAULT_TOLERANT_FAT_LOG_ENTRY_SIZE)) || |
| 137 |
2/2✓ Branch 13 → 14 taken 163558949 times.
✓ Branch 13 → 15 taken 12 times.
|
163558961 | ((log_type == FX_FAULT_TOLERANT_DIR_LOG_TYPE) && |
| 138 |
2/2✓ Branch 14 → 15 taken 8 times.
✓ Branch 14 → 16 taken 163563037 times.
|
163563045 | (log_len < FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE)) || |
| 139 | (log_len > size)) | ||
| 140 | { | ||
| 141 | |||
| 142 | /* Something wrong with log file. */ | ||
| 143 | 24 | return(FX_FILE_CORRUPT); | |
| 144 | } | ||
| 145 | |||
| 146 | /* Reduce the total log file size. */ | ||
| 147 | 163563037 | size -= log_len; | |
| 148 | |||
| 149 | /* Process log entry by type. */ | ||
| 150 |
3/3✓ Branch 16 → 17 taken 4092 times.
✓ Branch 16 → 23 taken 163558941 times.
✓ Branch 16 → 34 taken 4 times.
|
163563037 | switch (log_type) |
| 151 | { | ||
| 152 | 4092 | case FX_FAULT_TOLERANT_FAT_LOG_TYPE: | |
| 153 | |||
| 154 | /* This is a FAT log. */ | ||
| 155 | 4092 | fat_log = (FX_FAULT_TOLERANT_FAT_LOG *)current_ptr; | |
| 156 | |||
| 157 | /* Write FAT entry. */ | ||
| 158 | 4092 | status = _fx_utility_FAT_entry_write(media_ptr, | |
| 159 | 4092 | _fx_utility_32_unsigned_read((UCHAR *)&fat_log -> fx_fault_tolerant_FAT_log_cluster), | |
| 160 | 4092 | _fx_utility_32_unsigned_read((UCHAR *)&fat_log -> fx_fault_tolerant_FAT_log_value)); | |
| 161 | |||
| 162 |
2/2✓ Branch 20 → 21 taken 4 times.
✓ Branch 20 → 22 taken 4088 times.
|
4092 | if (status != FX_SUCCESS) |
| 163 | { | ||
| 164 | |||
| 165 | /* Return the error status. */ | ||
| 166 | 4 | return(status); | |
| 167 | } | ||
| 168 | 4088 | break; | |
| 169 | |||
| 170 | 163558941 | case FX_FAULT_TOLERANT_DIR_LOG_TYPE: | |
| 171 | |||
| 172 | /* This is a DIR log. */ | ||
| 173 | 163558941 | dir_log = (FX_FAULT_TOLERANT_DIR_LOG *)current_ptr; | |
| 174 | |||
| 175 | 163558941 | log_sector = _fx_utility_64_unsigned_read((UCHAR *)&dir_log -> fx_fault_tolerant_dir_log_sector); | |
| 176 | |||
| 177 | /* Get the destination sector. */ | ||
| 178 | 163558941 | status = _fx_utility_logical_sector_read(media_ptr, | |
| 179 | log_sector, | ||
| 180 | 163558941 | media_ptr -> fx_media_memory_buffer, | |
| 181 | ((ULONG) 1), FX_DATA_SECTOR); | ||
| 182 | |||
| 183 |
2/2✓ Branch 25 → 26 taken 16 times.
✓ Branch 25 → 27 taken 163558925 times.
|
163558941 | if (status != FX_SUCCESS) |
| 184 | { | ||
| 185 | |||
| 186 | /* Return the error status. */ | ||
| 187 | 16 | return(status); | |
| 188 | } | ||
| 189 | |||
| 190 | /* Set copy information. */ | ||
| 191 | 163558925 | copy_offset = _fx_utility_32_unsigned_read((UCHAR *)&dir_log -> fx_fault_tolerant_dir_log_offset); | |
| 192 | |||
| 193 | |||
| 194 | 163558925 | copy_size = log_len - FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE; | |
| 195 | |||
| 196 |
2/2✓ Branch 28 → 29 taken 8 times.
✓ Branch 28 → 30 taken 163558917 times.
|
163558925 | if (((ULONG64)copy_offset + (ULONG64)copy_size) > (ULONG64)(media_ptr -> fx_media_bytes_per_sector)) |
| 197 | { | ||
| 198 | 8 | return(FX_FILE_CORRUPT); | |
| 199 | } | ||
| 200 | |||
| 201 | /* Copy data into destination sector. */ | ||
| 202 | 163558917 | memcpy(media_ptr -> fx_media_memory_buffer + copy_offset, /* Use case of memcpy is verified. */ | |
| 203 | 163558917 | current_ptr + FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE, copy_size); | |
| 204 | |||
| 205 | |||
| 206 | /* Write back the current logical sector. */ | ||
| 207 | 163558917 | status = _fx_utility_logical_sector_write(media_ptr, | |
| 208 | log_sector, | ||
| 209 | 163558917 | media_ptr -> fx_media_memory_buffer, | |
| 210 | ((ULONG) 1), FX_DIRECTORY_SECTOR); | ||
| 211 | |||
| 212 |
2/2✓ Branch 31 → 32 taken 4 times.
✓ Branch 31 → 33 taken 163558577 times.
|
163558581 | if (status != FX_SUCCESS) |
| 213 | { | ||
| 214 | |||
| 215 | /* Return the error status. */ | ||
| 216 | 4 | return(status); | |
| 217 | } | ||
| 218 | 163558577 | break; | |
| 219 | |||
| 220 | 4 | default: | |
| 221 | |||
| 222 | /* Wrong type. */ | ||
| 223 | 4 | return(FX_SECTOR_INVALID); | |
| 224 | } | ||
| 225 | |||
| 226 | /* Decrement the remaining log counter. */ | ||
| 227 | 163562665 | remaining_logs--; | |
| 228 | |||
| 229 | /* Move to start position of next log entry. */ | ||
| 230 | 163562665 | current_ptr += log_len; | |
| 231 | } | ||
| 232 | |||
| 233 | /* Check whether or not to process FAT chain. */ | ||
| 234 |
2/2✓ Branch 37 → 38 taken 8413279 times.
✓ Branch 37 → 41 taken 151730329 times.
|
160143608 | if (FAT_chain -> fx_fault_tolerant_FAT_chain_flag & FX_FAULT_TOLERANT_FLAG_FAT_CHAIN_VALID) |
| 235 | { | ||
| 236 | |||
| 237 | /* Free old link of FAT. */ | ||
| 238 | 8413279 | status = _fx_fault_tolerant_cleanup_FAT_chain(media_ptr, FX_FAULT_TOLERANT_FAT_CHAIN_CLEANUP); | |
| 239 |
2/2✓ Branch 39 → 40 taken 12 times.
✓ Branch 39 → 41 taken 8413221 times.
|
8413233 | if (status != FX_SUCCESS) |
| 240 | { | ||
| 241 | |||
| 242 | /* Return the error status. */ | ||
| 243 | 12 | return(status); | |
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | /* Flush the internal logical sector cache. */ | ||
| 248 | 160143550 | status = _fx_utility_logical_sector_flush(media_ptr, 1, (ULONG64) media_ptr -> fx_media_total_sectors, FX_FALSE); | |
| 249 | |||
| 250 | /* Check for a bad status. */ | ||
| 251 |
2/2✓ Branch 42 → 43 taken 2 times.
✓ Branch 42 → 44 taken 160143548 times.
|
160143550 | if (status != FX_SUCCESS) |
| 252 | { | ||
| 253 | |||
| 254 | /* Return the bad status. */ | ||
| 255 | 2 | return(status); | |
| 256 | } | ||
| 257 | |||
| 258 | /* Flush FAT table. */ | ||
| 259 | #ifdef FX_FAULT_TOLERANT | ||
| 260 | |||
| 261 | /* Ensure the new FAT chain is properly written to the media. */ | ||
| 262 | |||
| 263 | /* Flush the cached individual FAT entries */ | ||
| 264 | 160143548 | _fx_utility_FAT_flush(media_ptr); | |
| 265 | #endif | ||
| 266 | |||
| 267 | /* Return success. */ | ||
| 268 | 160143548 | return(FX_SUCCESS); | |
| 269 | } | ||
| 270 | #endif /* FX_ENABLE_FAULT_TOLERANT */ | ||
| 271 | |||
| 272 |