1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** FileX Component */ 16 /** */ 17 /** Fault Tolerant */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 23 /**************************************************************************/ 24 /* */ 25 /* COMPONENT DEFINITION RELEASE */ 26 /* */ 27 /* fx_fault_tolerant.h PORTABLE C */ 28 /* 6.1 */ 29 /* AUTHOR */ 30 /* */ 31 /* William E. Lamie, Microsoft Corporation */ 32 /* */ 33 /* DESCRIPTION */ 34 /* */ 35 /* This file defines the FileX Fault Tolerant component constants, */ 36 /* data definitions, and external references. It is assumed that */ 37 /* fx_api.h (and fx_port.h) have already been included. */ 38 /* */ 39 /* RELEASE HISTORY */ 40 /* */ 41 /* DATE NAME DESCRIPTION */ 42 /* */ 43 /* 05-19-2020 William E. Lamie Initial Version 6.0 */ 44 /* 09-30-2020 William E. Lamie Modified comment(s), */ 45 /* resulting in version 6.1 */ 46 /* */ 47 /**************************************************************************/ 48 49 #ifndef _FX_FAULT_TOLERANT_H_ 50 #define _FX_FAULT_TOLERANT_H_ 51 52 #ifdef FX_ENABLE_FAULT_TOLERANT 53 54 #ifndef FX_FAULT_TOLERANT 55 #error "FX_FAULT_TOLERANT must be defined with FX_ENABLE_FAULT_TOLERANT" 56 #endif /* FX_FAULT_TOLERANT */ 57 58 /* Define ID of fault tolerant. */ 59 #define FX_FAULT_TOLERANT_ID 0x46544C52 60 61 /* Define fault tolerant version. */ 62 #define FX_FAULT_TOLERANT_VERSION_MAJOR 0x01 63 #define FX_FAULT_TOLERANT_VERSION_MINOR 0x00 64 65 /* Define byte offset in boot sector where the cluster number of the Fault Tolerant Log file is. 66 Note that this field (byte 116 to 119) is marked as reserved by FAT 12/16/32 specification. */ 67 #ifndef FX_FAULT_TOLERANT_BOOT_INDEX 68 #define FX_FAULT_TOLERANT_BOOT_INDEX 116 69 #endif /* FX_FAULT_TOLERANT_BOOT_INDEX */ 70 71 /* Define the extension invoked when fault tolerant log is recovered or applied during enable API. */ 72 #ifndef FX_FAULT_TOLERANT_ENABLE_EXTENSION 73 #define FX_FAULT_TOLERANT_ENABLE_EXTENSION 74 #endif /* FX_FAULT_TOLERANT_ENABLE_EXTENSION */ 75 76 /* Define the extension invoked when fault tolerant log is applied. */ 77 #ifndef FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION 78 #define FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION 79 #endif /* FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION */ 80 81 /* If not-defined, default port-specific processing extensions to white space. */ 82 #ifndef FX_FAULT_TOLERANT_WRITE_LOG_FILE_EXTENSION 83 #define FX_FAULT_TOLERANT_WRITE_LOG_FILE_EXTENSION 84 #endif /* FX_FAULT_TOLERANT_WRITE_LOG_FILE_EXTENSION */ 85 86 /* Define the maximum size of log file. */ 87 #define FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE 3072 88 89 /* For backward compatibility, map the symbols deprecated to FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE. */ 90 #ifndef FX_FAULT_TOLERANT_MINIMAL_CLUSTER 91 #define FX_FAULT_TOLERANT_MINIMAL_CLUSTER FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE 92 #endif /* FX_FAULT_TOLERANT_MINIMAL_CLUSTER */ 93 #ifndef FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE 94 #define FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE 95 #endif /* FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE */ 96 97 /* Define the states of the fault tolerant module. */ 98 #define FX_FAULT_TOLERANT_STATE_IDLE 0x00u 99 #define FX_FAULT_TOLERANT_STATE_STARTED 0x01u 100 #define FX_FAULT_TOLERANT_STATE_SET_FAT_CHAIN 0x02u 101 102 /* Define types of logs. */ 103 #define FX_FAULT_TOLERANT_FAT_LOG_TYPE 1 104 #define FX_FAULT_TOLERANT_DIR_LOG_TYPE 2 105 #define FX_FAULT_TOLERANT_BITMAP_LOG_TYPE 3 106 107 /* Define operations of FAT chain. */ 108 #define FX_FAULT_TOLERANT_FAT_CHAIN_RECOVER 0 /* Recover new FAT chain. */ 109 #define FX_FAULT_TOLERANT_FAT_CHAIN_CLEANUP 1 /* Cleanup old FAT chain. */ 110 111 /* Define flags for FAT chain log. */ 112 #define FX_FAULT_TOLERANT_FLAG_FAT_CHAIN_VALID 0x01 113 #define FX_FAULT_TOLERANT_FLAG_BITMAP_USED 0x02 114 115 /* Define size of each section in log file. */ 116 #define FX_FAULT_TOLERANT_LOG_HEADER_SIZE sizeof(FX_FAULT_TOLERANT_LOG_HEADER) 117 #define FX_FAULT_TOLERANT_FAT_CHAIN_SIZE sizeof(FX_FAULT_TOLERANT_FAT_CHAIN) 118 #define FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE sizeof(FX_FAULT_TOLERANT_LOG_CONTENT) 119 120 /* Define offset of each section in log file. */ 121 #define FX_FAULT_TOLERANT_FAT_CHAIN_OFFSET (FX_FAULT_TOLERANT_LOG_HEADER_SIZE) 122 #define FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET (FX_FAULT_TOLERANT_LOG_HEADER_SIZE + FX_FAULT_TOLERANT_FAT_CHAIN_SIZE) 123 124 /* Define size of log entries. */ 125 /* The total size of DIR log entry is variable. 16 is the fixed size of DIR log entry. */ 126 #define FX_FAULT_TOLERANT_FAT_LOG_ENTRY_SIZE sizeof(FX_FAULT_TOLERANT_FAT_LOG) 127 #define FX_FAULT_TOLERANT_BITMAP_LOG_ENTRY_SIZE sizeof(FX_FAULT_TOLERANT_BITMAP_LOG) 128 #define FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE sizeof(FX_FAULT_TOLERANT_DIR_LOG) 129 130 #ifdef FX_FAULT_TOLERANT_TRANSACTION_FAIL_FUNCTION 131 #define FX_FAULT_TOLERANT_TRANSACTION_FAIL _fx_fault_tolerant_transaction_fail 132 #else 133 /* Define transaction fail for fault tolerant. */ 134 #define FX_FAULT_TOLERANT_TRANSACTION_FAIL(m) \ 135 if ((m) -> fx_media_fault_tolerant_enabled == FX_TRUE) \ 136 { \ 137 (m) -> fx_media_fault_tolerant_transaction_count--; \ 138 if ((m) -> fx_media_fault_tolerant_transaction_count == 0) \ 139 { \ 140 _fx_fault_tolerant_recover(m); \ 141 _fx_fault_tolerant_reset_log_file(m); \ 142 } \ 143 } 144 145 #endif /* FX_FAULT_TOLERANT_TRANSACTION_FAIL_FUNCTION */ 146 147 /* Log file format 148 * The entire log file fits into one cluster. 149 * 150 * 1 2 3 151 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 152 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 153 * + ID + 154 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 155 * + Total Log Size (in Bytes) + Header Checksum + Log Header 156 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 157 * + version major + version minor + reserved + 158 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 159 * + Checksum of FAT chain + Flag | Reserved + 160 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 161 * + Insertion Point - Front + 162 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 163 * + Head cluster of newly created FAT chain + 164 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FAT Chain 165 * + Head cluster of original FAT chain + 166 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 167 * + Insertion Point - Back + 168 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 169 * + Next Deletion Point + 170 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 171 * + checksum of log content + count of log entries + 172 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 173 * + (log 0) . + 174 * + . + 175 * + . + 176 * + . + 177 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 178 * + (log 1) . + 179 * + . + Log Entries 180 * + . + 181 * + . + 182 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 183 * + ... + 184 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 185 * + (log N) . + 186 * + . + 187 * + . + 188 * + . + 189 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 190 * 191 * 192 * Log Header 193 * 194 * * ID: It is fixed value FX_FAULT_TOLERANT_ID. 195 * * Total Size: Total size (in bytes) of the log file, including Log Header, FAT Chain and Log Entries 196 * * Header Checksum: It is the checksum of all data in log header. 197 * * Version Major: The major version number. 198 * * Version Minor: The minor version number. 199 * * Reserved: Reserved for future use. 200 * 201 * FAT Chain 202 * 203 * * Checksum of FAT chain: It is the checksum of all data in the FAT Chain section. 204 * * Flag: 8 bits. The 1-6 bits are not used (from left to right). 205 * bit 7: When set, bitmap is used in old FAT chain. 206 * bit 8: When set, FAT chain is valid. 207 * * Reserved: Reserved for future use. 208 * * Insertion Point - Front: The cluster where the newly created chain is attached to 209 * * Head cluster of new FAT chain. It is the head cluster of new FAT chain. 210 * * Head cluster of oritinal FAT chain. It is the head cluster of the original FAT chain, 211 * which will be removed. 212 * * Inswertion Point - Back: The original cluster right after the newly created chain is inserted. 213 * * Next Deletion Point: next session of cluster to delete. It is used during deleting FAT chain. 214 * The deltion is carried out in stages for perofmrance reasons. When delting a FAT chain, the 215 * Next Deletion Point is chosen, and the chain between head and the Next Deletion Point is deleted. 216 * 217 * Log Entries: 218 * 219 * * Checksum of log entries: It is the checksum of all data in Log Entries 220 * * Counter of log entries: It is the counter of all log entries in Log content. 221 * * log 0 ... log N: Log entries. The formats are described below. 222 */ 223 224 /* Defined structure of log header. 225 226 227 */ 228 typedef struct FX_FAULT_TOLERANT_LOG_HEADER_STRUCT 229 { 230 ULONG fx_fault_tolerant_log_header_id; 231 USHORT fx_fault_tolerant_log_header_total_size; 232 USHORT fx_fault_tolerant_log_header_checksum; 233 UCHAR fx_fault_tolerant_log_header_version_major; 234 UCHAR fx_fault_tolerant_log_header_version_minor; 235 USHORT fx_fault_tolerant_log_header_reserved; 236 } FX_FAULT_TOLERANT_LOG_HEADER; 237 238 /* Define structure of FAT chain. */ 239 typedef struct FX_FAULT_TOLERANT_FAT_CHAIN_STRUCT 240 { 241 USHORT fx_fault_tolerant_FAT_chain_checksumm; 242 UCHAR fx_fault_tolerant_FAT_chain_flag; 243 UCHAR fx_fault_tolerant_FAT_chain_reserved; 244 245 ULONG fx_fault_tolerant_FAT_chain_insertion_front; 246 ULONG fx_fault_tolerant_FAT_chain_head_new; 247 ULONG fx_fault_tolerant_FAT_chain_head_original; 248 ULONG fx_fault_tolerant_FAT_chain_insertion_back; 249 ULONG fx_fault_tolerant_FAT_chain_next_deletion; 250 } FX_FAULT_TOLERANT_FAT_CHAIN; 251 252 253 /* Define structure of Log content. */ 254 typedef struct FX_FAULT_TOLERANT_LOG_CONTENT_STRUCT 255 { 256 USHORT fx_fault_tolerant_log_content_checksum; 257 USHORT fx_fault_tolerant_log_content_count; 258 } FX_FAULT_TOLERANT_LOG_CONTENT; 259 260 261 /* 3 types of log entries are defined. */ 262 /* FAT log format 263 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 264 * + type + size + 265 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 266 * + cluster + 267 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 268 * + value + 269 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 270 * 271 * Description: 272 * 273 * Type: FX_FAULT_TOLERANT_FAT_LOG. 274 * Size: The size of this log entry. 275 * Cluster: The cluster number in FAT. 276 * Value: The value of cluster in FAT. 277 * 278 */ 279 typedef struct FX_FAULT_TOLERANT_FAT_LOG_STRUCT 280 { 281 USHORT fx_fault_tolerant_FAT_log_type; 282 USHORT fx_fault_tolerant_FAT_log_size; 283 ULONG fx_fault_tolerant_FAT_log_cluster; 284 ULONG fx_fault_tolerant_FAT_log_value; 285 } FX_FAULT_TOLERANT_FAT_LOG; 286 287 /* DIR log format 288 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 289 * + type + size + 290 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 291 * + sector offset + 292 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 293 * + log sector + 294 * + + 295 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 296 * + log data + 297 * + . + 298 * + . + 299 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 300 * 301 * Fields description, 302 * 303 * Type: FX_FAULT_TOLERANT_DIRECTORY_LOG 304 * Size: The size of this log entry. 305 * Sector Offset: The offset in original sector this DIR is trying to write to. 306 * Log Sector: The original sector this DIR is trying to write to. 307 * Log Data: Content of DIR entries. 308 * 309 */ 310 typedef struct FX_FAULT_TOLERANT_DIR_LOG_STRUCT 311 { 312 USHORT fx_fault_tolerant_dir_log_type; 313 USHORT fx_fault_tolerant_dir_log_size; 314 ULONG fx_fault_tolerant_dir_log_offset; 315 ULONG64 fx_fault_tolerant_dir_log_sector; 316 } FX_FAULT_TOLERANT_DIR_LOG; 317 318 /* Bitmap log format 319 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 320 * + type + size + 321 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 322 * + cluster + 323 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 324 * + value + 325 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 326 * 327 * Description, 328 * 329 * Type: FX_FAULT_TOLERANT_BITMAP_LOG. 330 * Size: The size of this log entry. 331 * Cluster: The cluster number in FAT. 332 * Value: The value of cluster in FAT. 333 */ 334 typedef struct FX_FAULT_TOLERANT_BITMAP_LOG_STRUCT 335 { 336 USHORT fx_fault_tolerant_bitmap_log_type; 337 USHORT fx_fault_tolerant_bitmap_log_size; 338 ULONG fx_fault_tolerant_bitmap_log_cluster; 339 ULONG fx_fault_tolerant_bitmap_log_value; 340 } FX_FAULT_TOLERANT_BITMAP_LOG; 341 342 343 /* This function checks whether or not the log file exists, and creates the log file if it does not exist. */ 344 UINT _fx_fault_tolerant_enable(FX_MEDIA *media_ptr, VOID *memory_buffer, UINT memory_size); 345 UINT _fxe_fault_tolerant_enable(FX_MEDIA *media_ptr, VOID *memory_buffer, UINT memory_size); 346 347 /* This function resets statistics and marks the start of a transaction. */ 348 UINT _fx_fault_tolerant_transaction_start(FX_MEDIA *media_ptr); 349 350 /* This function marks the end of a transaction and completes the log file. 351 * Then it applies all data in the log file to the file system. 352 * Finally it resets the log header section. */ 353 UINT _fx_fault_tolerant_transaction_end(FX_MEDIA *media_ptr); 354 355 /* This function resets the log file. */ 356 UINT _fx_fault_tolerant_reset_log_file(FX_MEDIA *media_ptr); 357 358 /* This function applies the log file to the file system. */ 359 UINT _fx_fault_tolerant_apply_logs(FX_MEDIA *media_ptr); 360 361 /* This function recovers FAT chain. */ 362 UINT _fx_fault_tolerant_recover(FX_MEDIA *media_ptr); 363 364 /* This function adds a FAT log entry. */ 365 UINT _fx_fault_tolerant_add_FAT_log(FX_MEDIA *media_ptr, ULONG cluster, ULONG value); 366 367 /* This function adds a directory log entry. */ 368 UINT _fx_fault_tolerant_add_dir_log(FX_MEDIA *media_ptr, ULONG64 logical_sector, ULONG offset, 369 UCHAR *data, ULONG data_size); 370 371 /* This function sets the FAT chain. */ 372 UINT _fx_fault_tolerant_set_FAT_chain(FX_MEDIA *media_ptr, UINT use_bitmap, ULONG insertion_front, 373 ULONG new_head_cluster, ULONG original_head_cluster, ULONG insertion_back); 374 375 /* This function reads a FAT entry from log file. If it doesn't exist in log file, return and read from FAT entry directly. */ 376 UINT _fx_fault_tolerant_read_FAT(FX_MEDIA *media_ptr, ULONG cluster, ULONG *value, ULONG log_type); 377 378 /* This function reads directory sector from log file. */ 379 UINT _fx_fault_tolerant_read_directory_sector(FX_MEDIA *media_ptr, ULONG64 logical_sector, 380 VOID *buffer_ptr, ULONG64 sectors); 381 382 /* This function calculates the checksum of the log header. */ 383 USHORT _fx_fault_tolerant_calculate_checksum(UCHAR *data, UINT len); 384 385 /* This function cleans up FAT chain. */ 386 UINT _fx_fault_tolerant_cleanup_FAT_chain(FX_MEDIA *media_ptr, UINT operation); 387 388 /* This function reads log file from file system to memory buffer. */ 389 UINT _fx_fault_tolerant_read_log_file(FX_MEDIA *media_ptr); 390 391 /* This function writes data of one sector from memory to log file in file system. */ 392 UINT _fx_fault_tolerant_write_log_file(FX_MEDIA *media_ptr, ULONG relative_sector); 393 394 /* This function creates log file. */ 395 UINT _fx_fault_tolerant_create_log_file(FX_MEDIA *media_ptr); 396 397 #ifdef FX_FAULT_TOLERANT_TRANSACTION_FAIL_FUNCTION 398 /* This function cleans up resources created by fault tolerant when transaction fails. */ 399 UINT _fx_fault_tolerant_transaction_fail(FX_MEDIA *media_ptr); 400 #endif /* FX_FAULT_TOLERANT_TRANSACTION_FAIL_FUNCTION */ 401 402 403 #endif /* FX_ENABLE_FAULT_TOLERANT */ 404 405 #endif /* _FX_FAULT_TOLERANT_H_ */ 406 407