GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 122 / 0 / 122
Functions: 100.0% 1 / 0 / 1
Branches: 100.0% 257 / 0 / 257

fx_fault_tolerant_enable.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_directory.h"
30 #include "fx_fault_tolerant.h"
31
32
33 #ifdef FX_ENABLE_FAULT_TOLERANT
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _fx_fault_tolerant_enable PORTABLE C */
39 /* 6.2.0 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function enables the FileX Fault Tolerant feature. It first */
47 /* searches for a valid log file. A valid log file indicates the */
48 /* previous write operation failed, and appropriate action now must */
49 /* be taken to restore the integrity of the file system. Once the */
50 /* recovery effort is completed, the file system is properly restored. */
51 /* An empty log file indicates the previous write operation was */
52 /* successfully completed and no action needs to be taken at this */
53 /* point. If the file system does not have a log file, or the */
54 /* checksum is not valid, it is an indication either the file system */
55 /* is not under the protection of FileX Fault Tolerant. A new log */
56 /* file is created. */
57 /* */
58 /* INPUT */
59 /* */
60 /* media_ptr Media control block pointer */
61 /* memory_buffer Pointer to memory buffer. */
62 /* memory_size Size of memory buffer. */
63 /* */
64 /* OUTPUT */
65 /* */
66 /* return status */
67 /* */
68 /* CALLS */
69 /* */
70 /* _fx_fault_tolerant_calculate_checksum Compute Checksum of data */
71 /* _fx_fault_tolerant_apply_logs Apply logs into file system */
72 /* _fx_fault_tolerant_recover Recover FAT chain */
73 /* _fx_fault_tolerant_reset_log_file Reset the log file */
74 /* _fx_fault_tolerant_read_log_file Read log file to cache */
75 /* _fx_utility_FAT_entry_read Read a FAT entry */
76 /* _fx_utility_16_unsigned_read Read a USHORT from memory */
77 /* _fx_utility_32_unsigned_read Read a ULONG from memory */
78 /* */
79 /* CALLED BY */
80 /* */
81 /* Application Code */
82 /* */
83 /**************************************************************************/
84 2716 UINT _fx_fault_tolerant_enable(FX_MEDIA *media_ptr, VOID *memory_buffer, UINT memory_size)
85 {
86 ULONG start_cluster;
87 ULONG FAT_value;
88 UINT status;
89 ULONG checksum;
90 ULONG total_size;
91 FX_FAULT_TOLERANT_LOG_HEADER *log_header;
92 FX_FAULT_TOLERANT_FAT_CHAIN *FAT_chain;
93 ULONG cluster_number;
94 ULONG i, j;
95 ULONG FAT_entry, FAT_sector, FAT_read_sectors;
96 ULONG bytes_in_buffer;
97 ULONG clusters;
98 ULONG bytes_per_sector;
99 ULONG bytes_per_cluster;
100
101 /* Protect against other threads accessing the media. */
102 1390 FX_PROTECT
103
104 /* Calculate clusters needed for fault tolerant log. */
105 2716 bytes_per_sector = media_ptr -> fx_media_bytes_per_sector;
106 2716 bytes_per_cluster = bytes_per_sector * media_ptr -> fx_media_sectors_per_cluster;
107
108
4/4
✓ Branch 2 → 3 taken 6 times.
✓ Branch 2 → 4 taken 1320 times.
✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 6 taken 1384 times.
2716 if (bytes_per_cluster == 0)
109 {
110
111 /* Release media protection. */
112 6 FX_UNPROTECT
113
114 12 return(FX_MEDIA_INVALID);
115 }
116
117 2704 clusters = (FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE + bytes_per_cluster - 1) / bytes_per_cluster;
118 2704 media_ptr -> fx_media_fault_tolerant_clusters = clusters;
119
120 /* Check buffer size requirement. */
121
4/4
✓ Branch 4 → 5 taken 6 times.
✓ Branch 4 → 6 taken 1314 times.
✓ Branch 6 → 7 taken 6 times.
✓ Branch 6 → 9 taken 1378 times.
2704 if (memory_size < bytes_per_sector)
122 {
123
124 /* Release media protection. */
125 6 FX_UNPROTECT
126
127 12 return(FX_NOT_ENOUGH_MEMORY);
128 }
129
130
131
6/6
✓ Branch 6 → 7 taken 62 times.
✓ Branch 6 → 21 taken 626 times.
✓ Branch 6 → 24 taken 626 times.
✓ Branch 9 → 10 taken 62 times.
✓ Branch 9 → 25 taken 658 times.
✓ Branch 9 → 28 taken 658 times.
2692 if (media_ptr -> fx_media_FAT32_additional_info_sector)
132 {
133
134 /* A 32-bit FAT is present. Read directly into the logical sector
135 cache memory to optimize I/O on larger devices. Since we are looking for
136 values of zero, endian issues are not important. */
137 /* Force update the available cluster. */
138
139 #ifndef FX_DISABLE_CACHE
140 /* Invalidate the current logical sector cache. */
141 62 _fx_utility_logical_sector_flush(media_ptr, ((ULONG64) 1), (ULONG64) (media_ptr -> fx_media_total_sectors), FX_TRUE);
142
143 /* Reset the memory pointer. */
144 62 media_ptr -> fx_media_memory_buffer = media_ptr -> fx_media_sector_cache[0].fx_cached_sector_memory_buffer;
145 #endif /* FX_DISABLE_CACHE */
146
147 /* Reset the available cluster. */
148 124 media_ptr -> fx_media_available_clusters = 0;
149
150 /* Loop through all FAT sectors in the primary FAT. The first two entries are
151 examined in this loop, but they are always unavailable. */
152 124 cluster_number = 0;
153 #ifndef FX_DISABLE_CACHE
154
4/4
✓ Branch 23 → 9 taken 3505 times.
✓ Branch 23 → 24 taken 30 times.
✓ Branch 27 → 12 taken 3505 times.
✓ Branch 27 → 28 taken 30 times.
7070 for (i = 0; i < media_ptr -> fx_media_sectors_per_FAT; i = i + media_ptr -> fx_media_sector_cache_size)
155 {
156
157 /* Calculate the starting next FAT sector. */
158 7010 FAT_sector = media_ptr -> fx_media_reserved_sectors + i;
159
160 /* Calculate how many sectors to read. */
161 7010 FAT_read_sectors = media_ptr -> fx_media_sectors_per_FAT - i;
162
163 /* Determine if there is not enough memory to read the remaining FAT sectors. */
164
4/4
✓ Branch 9 → 10 taken 3486 times.
✓ Branch 9 → 11 taken 19 times.
✓ Branch 12 → 13 taken 3486 times.
✓ Branch 12 → 14 taken 19 times.
7010 if (FAT_read_sectors > media_ptr -> fx_media_sector_cache_size)
165 {
166 6972 FAT_read_sectors = media_ptr -> fx_media_sector_cache_size;
167 }
168 #else
169 /* Reset the buffer sector. */
170 62 media_ptr -> fx_media_memory_buffer_sector = (ULONG64)-1;
171
4/4
✓ Branch 20 → 8 taken 16351 times.
✓ Branch 20 → 21 taken 30 times.
✓ Branch 24 → 11 taken 16351 times.
✓ Branch 24 → 25 taken 30 times.
32762 for (i = 0; i < media_ptr -> fx_media_sectors_per_FAT; i++)
172 {
173
174 /* Calculate the starting next FAT sector. */
175 32702 FAT_sector = media_ptr -> fx_media_reserved_sectors + i;
176
177 /* Calculate how many sectors to read. */
178 32702 FAT_read_sectors = 1;
179 #endif /* FX_DISABLE_CACHE */
180
181 /* Read the FAT sectors directly from the driver. */
182 39712 media_ptr -> fx_media_driver_request = FX_DRIVER_READ;
183 39712 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
184 39712 media_ptr -> fx_media_driver_buffer = media_ptr -> fx_media_memory_buffer;
185 39712 media_ptr -> fx_media_driver_logical_sector = FAT_sector;
186 39712 media_ptr -> fx_media_driver_sectors = FAT_read_sectors;
187 39712 media_ptr -> fx_media_driver_sector_type = FX_FAT_SECTOR;
188
189 /* If trace is enabled, insert this event into the trace buffer. */
190 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_READ, media_ptr, FAT_sector, FAT_read_sectors, media_ptr -> fx_media_memory_buffer, FX_TRACE_INTERNAL_EVENTS, 0, 0)
191
192 /* Invoke the driver to read the FAT sectors. */
193 39712 (media_ptr -> fx_media_driver_entry) (media_ptr);
194
195 /* Determine if the read was successful. */
196
7/7
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 11 taken 16350 times.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 14 taken 3504 times.
✓ Branch 12 → 15 taken 16350 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 18 taken 3504 times.
39712 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
197 {
198
199 /* Release media protection. */
200 2 FX_UNPROTECT
201
202 4 return(FX_FAT_READ_ERROR);
203 }
204
205 /* Calculate the number of bytes in the buffer. */
206 39708 bytes_in_buffer = (media_ptr -> fx_media_bytes_per_sector * FAT_read_sectors);
207
208 /* Walk through the sector cache memory to search for available clusters and the first
209 available if not already found. */
210
8/8
✓ Branch 18 → 12 taken 2091606 times.
✓ Branch 18 → 19 taken 16320 times.
✓ Branch 21 → 15 taken 2091606 times.
✓ Branch 21 → 22 taken 3474 times.
✓ Branch 22 → 16 taken 2091606 times.
✓ Branch 22 → 23 taken 16320 times.
✓ Branch 25 → 19 taken 2091606 times.
✓ Branch 25 → 26 taken 3474 times.
8406012 for (j = 0; j < bytes_in_buffer;)
211 {
212
213 /* Pickup 32-bit FAT entry. */
214 8366424 FAT_entry = *((ULONG *)&(media_ptr -> fx_media_memory_buffer[j]));
215
216 /* Advance to next FAT entry. */
217 8366424 j = j + 4;
218
219 /* Determine if the FAT entry is free. */
220
8/8
✓ Branch 12 → 13 taken 2090860 times.
✓ Branch 12 → 15 taken 746 times.
✓ Branch 15 → 16 taken 2090860 times.
✓ Branch 15 → 18 taken 746 times.
✓ Branch 16 → 17 taken 2090860 times.
✓ Branch 16 → 19 taken 746 times.
✓ Branch 19 → 20 taken 2090860 times.
✓ Branch 19 → 22 taken 746 times.
8366424 if (FAT_entry == FX_FREE_CLUSTER)
221 {
222
223 /* Entry is free, increment available clusters. */
224 8363440 media_ptr -> fx_media_available_clusters++;
225
226 /* Determine if the starting free cluster has been found yet. */
227
8/8
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 2090859 times.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 18 taken 2090859 times.
✓ Branch 17 → 18 taken 1 time.
✓ Branch 17 → 19 taken 2090859 times.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 20 → 22 taken 2090859 times.
8363440 if (media_ptr -> fx_media_cluster_search_start == 0)
228 {
229
230 /* Remember the first free cluster to start further searches from. */
231 4 media_ptr -> fx_media_cluster_search_start = cluster_number;
232 }
233 }
234
235 /* Increment the cluster number. */
236 8366424 cluster_number++;
237
238 /* Determine if we have reviewed all FAT entries. */
239
8/8
✓ Branch 15 → 16 taken 30 times.
✓ Branch 15 → 17 taken 2091576 times.
✓ Branch 18 → 19 taken 30 times.
✓ Branch 18 → 20 taken 2091576 times.
✓ Branch 19 → 20 taken 30 times.
✓ Branch 19 → 21 taken 2091576 times.
✓ Branch 22 → 23 taken 30 times.
✓ Branch 22 → 24 taken 2091576 times.
8366424 if (cluster_number >= (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START))
240 {
241
242 /* Yes, we have looked at all the FAT entries. */
243
244 /* Ensure that the outer loop terminates as well. */
245 120 i = media_ptr -> fx_media_sectors_per_FAT;
246 120 break;
247 }
248 }
249 }
250 }
251
252 /* Store memory buffer and size. */
253 2688 media_ptr -> fx_media_fault_tolerant_memory_buffer = (UCHAR *)memory_buffer;
254
8/8
✓ Branch 21 → 22 taken 1 time.
✓ Branch 21 → 23 taken 655 times.
✓ Branch 24 → 25 taken 1 time.
✓ Branch 24 → 26 taken 655 times.
✓ Branch 25 → 26 taken 1 time.
✓ Branch 25 → 27 taken 687 times.
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 30 taken 687 times.
2688 if (memory_size > (clusters * bytes_per_cluster))
255 {
256 4 media_ptr -> fx_media_fault_tolerant_memory_buffer_size = clusters * bytes_per_cluster;
257 }
258 else
259 {
260 2684 media_ptr -> fx_media_fault_tolerant_memory_buffer_size = memory_size / bytes_per_sector * bytes_per_sector;
261 }
262
263 /* Read the boot sector from the device. */
264 2688 media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_READ;
265 2688 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
266 2688 media_ptr -> fx_media_driver_buffer = (UCHAR *)memory_buffer;
267 2688 media_ptr -> fx_media_driver_sectors = 1;
268 2688 media_ptr -> fx_media_driver_sector_type = FX_BOOT_SECTOR;
269
270 /* If trace is enabled, insert this event into the trace buffer. */
271 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_BOOT_READ, media_ptr, memory_buffer, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
272
273 /* Invoke the driver to read the boot sector. */
274 2688 (media_ptr -> fx_media_driver_entry) (media_ptr);
275
276 /* Determine if the boot sector was read correctly. */
277
8/8
✓ Branch 25 → 26 taken 3 times.
✓ Branch 25 → 27 taken 653 times.
✓ Branch 28 → 29 taken 3 times.
✓ Branch 28 → 30 taken 653 times.
✓ Branch 29 → 30 taken 3 times.
✓ Branch 29 → 32 taken 685 times.
✓ Branch 32 → 33 taken 3 times.
✓ Branch 32 → 35 taken 685 times.
2688 if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
278 {
279
280 /* Release media protection. */
281 6 FX_UNPROTECT
282
283 /* Return the boot sector error status. */
284 12 return(FX_BOOT_ERROR);
285 }
286
287 /* Check whether the boot index is used. */
288 2676 start_cluster = _fx_utility_32_unsigned_read((UCHAR *)memory_buffer + FX_FAULT_TOLERANT_BOOT_INDEX);
289
8/8
✓ Branch 28 → 29 taken 281 times.
✓ Branch 28 → 68 taken 372 times.
✓ Branch 31 → 32 taken 281 times.
✓ Branch 31 → 71 taken 372 times.
✓ Branch 33 → 34 taken 312 times.
✓ Branch 33 → 77 taken 373 times.
✓ Branch 36 → 37 taken 312 times.
✓ Branch 36 → 80 taken 373 times.
2676 if (start_cluster != 0)
290 {
291
292 /* The location of the fault tolerant log file is found. Need to verify the integrity of the log file. */
293
16/16
✓ Branch 29 → 30 taken 280 times.
✓ Branch 29 → 67 taken 1 time.
✓ Branch 30 → 31 taken 279 times.
✓ Branch 30 → 67 taken 1 time.
✓ Branch 32 → 33 taken 280 times.
✓ Branch 32 → 70 taken 1 time.
✓ Branch 33 → 34 taken 279 times.
✓ Branch 33 → 70 taken 1 time.
✓ Branch 34 → 35 taken 311 times.
✓ Branch 34 → 76 taken 1 time.
✓ Branch 35 → 36 taken 310 times.
✓ Branch 35 → 76 taken 1 time.
✓ Branch 37 → 38 taken 311 times.
✓ Branch 37 → 79 taken 1 time.
✓ Branch 38 → 39 taken 310 times.
✓ Branch 38 → 79 taken 1 time.
1186 if ((start_cluster >= FX_FAT_ENTRY_START) && (start_cluster < media_ptr -> fx_media_fat_reserved))
294 {
295
296 /* Check whether this cluster is used. */
297
8/8
✓ Branch 41 → 32 taken 571 times.
✓ Branch 41 → 42 taken 276 times.
✓ Branch 44 → 35 taken 571 times.
✓ Branch 44 → 45 taken 276 times.
✓ Branch 47 → 37 taken 633 times.
✓ Branch 47 → 48 taken 307 times.
✓ Branch 50 → 40 taken 633 times.
✓ Branch 50 → 51 taken 307 times.
3574 for (i = 0; i < clusters; i++)
298 {
299
300 /* Read FAT entry. */
301 2408 status = _fx_utility_FAT_entry_read(media_ptr, start_cluster + i, &FAT_value);
302
303 /* Check for a bad status. */
304
8/8
✓ Branch 33 → 34 taken 1 time.
✓ Branch 33 → 35 taken 570 times.
✓ Branch 36 → 37 taken 1 time.
✓ Branch 36 → 38 taken 570 times.
✓ Branch 38 → 39 taken 1 time.
✓ Branch 38 → 41 taken 632 times.
✓ Branch 41 → 42 taken 1 time.
✓ Branch 41 → 44 taken 632 times.
2408 if (status != FX_SUCCESS)
305 {
306
307 /* Release media protection. */
308 2 FX_UNPROTECT
309
310 /* Return the bad status. */
311 4 return(status);
312 }
313
314
8/8
✓ Branch 35 → 36 taken 293 times.
✓ Branch 35 → 38 taken 277 times.
✓ Branch 38 → 39 taken 293 times.
✓ Branch 38 → 41 taken 277 times.
✓ Branch 41 → 42 taken 324 times.
✓ Branch 41 → 44 taken 308 times.
✓ Branch 44 → 45 taken 324 times.
✓ Branch 44 → 47 taken 308 times.
2404 if (i < clusters - 1)
315 {
316
8/8
✓ Branch 36 → 37 taken 1 time.
✓ Branch 36 → 40 taken 292 times.
✓ Branch 39 → 40 taken 1 time.
✓ Branch 39 → 43 taken 292 times.
✓ Branch 42 → 43 taken 1 time.
✓ Branch 42 → 46 taken 323 times.
✓ Branch 45 → 46 taken 1 time.
✓ Branch 45 → 49 taken 323 times.
1234 if (FAT_value != (start_cluster + i + 1))
317 {
318
319 /* Mark invalid. */
320 4 start_cluster = 0;
321 4 break;
322 }
323 }
324
8/8
✓ Branch 38 → 39 taken 1 time.
✓ Branch 38 → 40 taken 276 times.
✓ Branch 41 → 42 taken 1 time.
✓ Branch 41 → 43 taken 276 times.
✓ Branch 44 → 45 taken 1 time.
✓ Branch 44 → 46 taken 307 times.
✓ Branch 47 → 48 taken 1 time.
✓ Branch 47 → 49 taken 307 times.
1170 else if (FAT_value != media_ptr -> fx_media_fat_last)
325 {
326
327 /* Mark invalid. */
328 4 start_cluster = 0;
329 4 break;
330 }
331 }
332
333 /* Is this FAT entry occupied by log file? */
334
8/8
✓ Branch 42 → 43 taken 276 times.
✓ Branch 42 → 66 taken 2 times.
✓ Branch 45 → 46 taken 276 times.
✓ Branch 45 → 69 taken 2 times.
✓ Branch 48 → 49 taken 307 times.
✓ Branch 48 → 75 taken 2 times.
✓ Branch 51 → 52 taken 307 times.
✓ Branch 51 → 78 taken 2 times.
1174 if (start_cluster)
335 {
336
337 /* Set the start cluster. */
338 1166 media_ptr -> fx_media_fault_tolerant_start_cluster = start_cluster;
339
340 /* Read log file from file system to memory. */
341 1166 status = _fx_fault_tolerant_read_log_file(media_ptr);
342
343 /* Check for good completion status. */
344
8/8
✓ Branch 44 → 45 taken 1 time.
✓ Branch 44 → 46 taken 275 times.
✓ Branch 47 → 48 taken 1 time.
✓ Branch 47 → 49 taken 275 times.
✓ Branch 50 → 51 taken 1 time.
✓ Branch 50 → 53 taken 306 times.
✓ Branch 53 → 54 taken 1 time.
✓ Branch 53 → 56 taken 306 times.
1166 if (status != FX_SUCCESS)
345 {
346
347 /* Release media protection. */
348 2 FX_UNPROTECT
349
350 /* Return the error status. */
351 4 return(status);
352 }
353
354 /* Set log header and FAT chain pointer. */
355 1162 log_header = (FX_FAULT_TOLERANT_LOG_HEADER *)media_ptr -> fx_media_fault_tolerant_memory_buffer;
356 1162 FAT_chain = (FX_FAULT_TOLERANT_FAT_CHAIN *)(media_ptr -> fx_media_fault_tolerant_memory_buffer +
357 FX_FAULT_TOLERANT_FAT_CHAIN_OFFSET);
358
359 /* Verify ID field. */
360
8/8
✓ Branch 47 → 48 taken 274 times.
✓ Branch 47 → 66 taken 1 time.
✓ Branch 50 → 51 taken 274 times.
✓ Branch 50 → 69 taken 1 time.
✓ Branch 54 → 55 taken 305 times.
✓ Branch 54 → 75 taken 1 time.
✓ Branch 57 → 58 taken 305 times.
✓ Branch 57 → 78 taken 1 time.
1162 if (_fx_utility_32_unsigned_read((UCHAR *)&log_header -> fx_fault_tolerant_log_header_id) == FX_FAULT_TOLERANT_ID)
361 {
362
363 /* Calculate checksum of log header. */
364 1158 checksum = _fx_fault_tolerant_calculate_checksum((UCHAR *)log_header,
365 FX_FAULT_TOLERANT_LOG_HEADER_SIZE);
366
367
8/8
✓ Branch 49 → 50 taken 273 times.
✓ Branch 49 → 66 taken 1 time.
✓ Branch 52 → 53 taken 273 times.
✓ Branch 52 → 69 taken 1 time.
✓ Branch 56 → 57 taken 304 times.
✓ Branch 56 → 75 taken 1 time.
✓ Branch 59 → 60 taken 304 times.
✓ Branch 59 → 78 taken 1 time.
1158 if (checksum == 0)
368 {
369
370 /* Fault tolerant log file is valid. */
371 /* Initialize file size. */
372 1154 total_size = _fx_utility_16_unsigned_read((UCHAR *)&log_header -> fx_fault_tolerant_log_header_total_size);
373
374 /* A reset log file carries just the header and the FAT chain, so that
375 is the smallest size on record. The log must also fit both the format
376 maximum and the buffer the caller supplied. */
377
16/16
✓ Branch 51 → 52 taken 272 times.
✓ Branch 51 → 54 taken 1 time.
✓ Branch 52 → 53 taken 271 times.
✓ Branch 52 → 54 taken 1 time.
✓ Branch 54 → 55 taken 272 times.
✓ Branch 54 → 57 taken 1 time.
✓ Branch 55 → 56 taken 271 times.
✓ Branch 55 → 57 taken 1 time.
✓ Branch 58 → 59 taken 303 times.
✓ Branch 58 → 61 taken 1 time.
✓ Branch 59 → 60 taken 302 times.
✓ Branch 59 → 61 taken 1 time.
✓ Branch 61 → 62 taken 303 times.
✓ Branch 61 → 64 taken 1 time.
✓ Branch 62 → 63 taken 302 times.
✓ Branch 62 → 64 taken 1 time.
1154 if ((total_size < FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET) ||
378 1146 (total_size > FX_FAULT_TOLERANT_MAXIMUM_LOG_FILE_SIZE) ||
379
8/8
✓ Branch 53 → 54 taken 1 time.
✓ Branch 53 → 55 taken 270 times.
✓ Branch 56 → 57 taken 1 time.
✓ Branch 56 → 58 taken 270 times.
✓ Branch 60 → 61 taken 1 time.
✓ Branch 60 → 63 taken 301 times.
✓ Branch 63 → 64 taken 1 time.
✓ Branch 63 → 66 taken 301 times.
1146 (total_size > media_ptr -> fx_media_fault_tolerant_memory_buffer_size))
380 {
381 6 FX_UNPROTECT
382 12 return(FX_FILE_CORRUPT);
383 }
384
385 1142 media_ptr -> fx_media_fault_tolerant_file_size = total_size;
386
387
388 /* Verify the checksum of the FAT chain. */
389 1142 checksum = _fx_fault_tolerant_calculate_checksum((UCHAR *)FAT_chain,
390 FX_FAULT_TOLERANT_FAT_CHAIN_SIZE);
391
392
8/8
✓ Branch 56 → 57 taken 269 times.
✓ Branch 56 → 66 taken 1 time.
✓ Branch 59 → 60 taken 269 times.
✓ Branch 59 → 69 taken 1 time.
✓ Branch 64 → 65 taken 300 times.
✓ Branch 64 → 75 taken 1 time.
✓ Branch 67 → 68 taken 300 times.
✓ Branch 67 → 78 taken 1 time.
1142 if (checksum == 0)
393 {
394
395 /* Checksum of FAT chain is correct. */
396
397
8/8
✓ Branch 57 → 58 taken 108 times.
✓ Branch 57 → 62 taken 161 times.
✓ Branch 60 → 61 taken 108 times.
✓ Branch 60 → 65 taken 161 times.
✓ Branch 65 → 66 taken 114 times.
✓ Branch 65 → 70 taken 186 times.
✓ Branch 68 → 69 taken 116 times.
✓ Branch 68 → 73 taken 184 times.
1138 if (total_size > (FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET + FX_FAULT_TOLERANT_LOG_HEADER_SIZE))
398 {
399
400 /* Log content is present. */
401 /* Now verify the checksum of log content. */
402 892 checksum = _fx_fault_tolerant_calculate_checksum((media_ptr -> fx_media_fault_tolerant_memory_buffer +
403 FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET),
404 446 (total_size - FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET));
405
8/8
✓ Branch 59 → 60 taken 107 times.
✓ Branch 59 → 64 taken 1 time.
✓ Branch 62 → 63 taken 107 times.
✓ Branch 62 → 67 taken 1 time.
✓ Branch 67 → 68 taken 113 times.
✓ Branch 67 → 72 taken 1 time.
✓ Branch 70 → 71 taken 115 times.
✓ Branch 70 → 75 taken 1 time.
446 if (checksum == 0)
406 {
407
408 /* Checksum of log content is correct. */
409
410 /* Extended port-specific processing macro, which is by default defined to white space. */
411 442 FX_FAULT_TOLERANT_ENABLE_EXTENSION
412
413 /* This is the situation where the log file contains log entries. This is an indication
414 that previous write operation did not complete successfully. Need to apply the log entries
415 to recover the previous write operation, effectively to finish up the previous write operation. */
416 442 status = _fx_fault_tolerant_apply_logs(media_ptr);
417 }
418 }
419 else
420 {
421
422 /* Extended port-specific processing macro, which is by default defined to white space. */
423 692 FX_FAULT_TOLERANT_ENABLE_EXTENSION
424
425 /* The log file does not contain log content but the FAT chain operation information is present.
426 This is the situation where the FAT chain has been modified but the rest of the content of these
427 clusters are not updated yet. In this situation, the previous FAT chain operation needs to be
428 reverted to restore the file system back to its state prior to the write operation. */
429 692 status = _fx_fault_tolerant_recover(media_ptr);
430 }
431
432
8/8
✓ Branch 64 → 65 taken 2 times.
✓ Branch 64 → 66 taken 261 times.
✓ Branch 67 → 68 taken 2 times.
✓ Branch 67 → 69 taken 261 times.
✓ Branch 72 → 73 taken 2 times.
✓ Branch 72 → 75 taken 292 times.
✓ Branch 75 → 76 taken 2 times.
✓ Branch 75 → 78 taken 292 times.
1114 if (status != FX_SUCCESS)
433 {
434
435 /* Release media protection. */
436 4 FX_UNPROTECT
437
438 /* Return the error status. */
439 8 return(status);
440 }
441 }
442 }
443 }
444 }
445 }
446 else
447 {
448
449 /* Not a valid cluster number. Set the flag to create a new log file. */
450 8 start_cluster = 0;
451 }
452 }
453
454 /* Check whether or not to create a log file. */
455
8/8
✓ Branch 68 → 69 taken 376 times.
✓ Branch 68 → 72 taken 264 times.
✓ Branch 71 → 72 taken 376 times.
✓ Branch 71 → 75 taken 264 times.
✓ Branch 77 → 78 taken 377 times.
✓ Branch 77 → 82 taken 295 times.
✓ Branch 80 → 81 taken 377 times.
✓ Branch 80 → 85 taken 295 times.
2624 if (start_cluster == 0)
456 {
457
458 /* Create log file. */
459 1506 status = _fx_fault_tolerant_create_log_file(media_ptr);
460
461
8/8
✓ Branch 70 → 71 taken 11 times.
✓ Branch 70 → 72 taken 365 times.
✓ Branch 73 → 74 taken 11 times.
✓ Branch 73 → 75 taken 365 times.
✓ Branch 79 → 80 taken 11 times.
✓ Branch 79 → 82 taken 366 times.
✓ Branch 82 → 83 taken 11 times.
✓ Branch 82 → 85 taken 366 times.
1506 if (status != FX_SUCCESS)
462 {
463
464 /* Release media protection. */
465 22 FX_UNPROTECT
466
467 /* Return the error status. */
468 44 return(status);
469 }
470 }
471
472 /* Reset log file. */
473 2580 status = _fx_fault_tolerant_reset_log_file(media_ptr);
474
475
8/8
✓ Branch 73 → 74 taken 1 time.
✓ Branch 73 → 75 taken 628 times.
✓ Branch 76 → 77 taken 1 time.
✓ Branch 76 → 78 taken 628 times.
✓ Branch 83 → 84 taken 1 time.
✓ Branch 83 → 86 taken 660 times.
✓ Branch 86 → 87 taken 1 time.
✓ Branch 86 → 89 taken 660 times.
2580 if (status != FX_SUCCESS)
476 {
477
478 /* Release media protection. */
479 2 FX_UNPROTECT
480
481 /* Return the error status. */
482 4 return(status);
483 }
484
485 /* Mark fault tolerant feature is enabled. */
486 2576 media_ptr -> fx_media_fault_tolerant_enabled = FX_TRUE;
487
488 /* Reset the transaction count. */
489 2576 media_ptr -> fx_media_fault_tolerant_transaction_count = 0;
490
491 /* Initialize the sector number of cached FAT entries. */
492 2576 media_ptr -> fx_media_fault_tolerant_cached_FAT_sector = 0;
493
494 /* Release media protection. */
495 1320 FX_UNPROTECT
496
497 /* Return the error status. */
498 2576 return(FX_SUCCESS);
499 }
500
501 #endif /* FX_ENABLE_FAULT_TOLERANT */
502
503