GCC Code Coverage Report


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

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