GCC Code Coverage Report


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

fx_utility_FAT_entry_write.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
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** FileX Component */
17 /** */
18 /** Utility */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define FX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "fx_api.h"
29 #include "fx_system.h"
30 #include "fx_utility.h"
31 #ifdef FX_ENABLE_FAULT_TOLERANT
32 #include "fx_fault_tolerant.h"
33 #endif /* FX_ENABLE_FAULT_TOLERANT */
34
35
36 /**************************************************************************/
37 /* */
38 /* FUNCTION RELEASE */
39 /* */
40 /* _fx_utility_FAT_entry_write PORTABLE C */
41 /* 6.1 */
42 /* AUTHOR */
43 /* */
44 /* William E. Lamie, Microsoft Corporation */
45 /* */
46 /* DESCRIPTION */
47 /* */
48 /* This function writes to the supplied FAT entry to all FATs in */
49 /* the media. 12-bit, 16-bit, and 32-bit FAT writing is supported. */
50 /* */
51 /* INPUT */
52 /* */
53 /* media_ptr Media control block pointer */
54 /* cluster Cluster entry number */
55 /* next_cluster Next cluster integer pointer */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* return status */
60 /* */
61 /* CALLS */
62 /* */
63 /* _fx_utility_FAT_flush FLUSH dirty entries in the */
64 /* FAT cache */
65 /* _fx_fault_tolerant_add_fat_log Add FAT redo log */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* FileX System Functions */
70 /* */
71 /**************************************************************************/
72 108727811 UINT _fx_utility_FAT_entry_write(FX_MEDIA *media_ptr, ULONG cluster, ULONG next_cluster)
73 {
74
75 UINT status, index, i;
76 FX_FAT_CACHE_ENTRY *cache_entry_ptr;
77 #ifdef FX_ENABLE_FAULT_TOLERANT
78 ULONG FAT_sector;
79
80 /* While fault_tolerant is enabled, only FAT entries in the same sector are allowed to be cached. */
81 /* We must flush FAT sectors in the order of FAT chains. */
82
2/2
✓ Branch 2 → 3 taken 79455392 times.
✓ Branch 2 → 12 taken 18052860 times.
97508252 if (media_ptr -> fx_media_fault_tolerant_enabled &&
83
2/2
✓ Branch 3 → 4 taken 45648601 times.
✓ Branch 3 → 12 taken 33806791 times.
79455392 (media_ptr -> fx_media_fault_tolerant_state & FX_FAULT_TOLERANT_STATE_STARTED))
84 {
85
86
2/2
✓ Branch 4 → 5 taken 4186 times.
✓ Branch 4 → 7 taken 45644415 times.
45648601 if (!(media_ptr -> fx_media_fault_tolerant_state & FX_FAULT_TOLERANT_STATE_SET_FAT_CHAIN))
87 {
88
89 /* Redirect this request to log file. */
90 4186 return(_fx_fault_tolerant_add_FAT_log(media_ptr, cluster, next_cluster));
91 }
92
93 /* Get sector number of the incoming FAT entry. */
94 45644415 FAT_sector = _fx_utility_FAT_sector_get(media_ptr, cluster);
95
96 /* Is FAT sector changed? */
97
2/2
✓ Branch 8 → 9 taken 5438041 times.
✓ Branch 8 → 12 taken 40206374 times.
45644415 if (FAT_sector != media_ptr -> fx_media_fault_tolerant_cached_FAT_sector)
98 {
99
100 /* Are there any cached FAT entries? */
101
2/2
✓ Branch 9 → 10 taken 251420 times.
✓ Branch 9 → 11 taken 5186621 times.
5438041 if (media_ptr -> fx_media_fault_tolerant_cached_FAT_sector)
102 {
103
104 /* Current FAT entry is located in different sector. Force flush. */
105 /* Flush the cached individual FAT entries */
106 251420 _fx_utility_FAT_flush(media_ptr);
107
108 }
109
110 /* Record sector number of current FAT entry. */
111 5438033 media_ptr -> fx_media_fault_tolerant_cached_FAT_sector = FAT_sector;
112 }
113 }
114 #endif /* FX_ENABLE_FAULT_TOLERANT */
115
116 #ifndef FX_MEDIA_STATISTICS_DISABLE
117 /* Increment the number of FAT entry writes and cache hits. */
118 108723617 media_ptr -> fx_media_fat_entry_writes++;
119 108723617 media_ptr -> fx_media_fat_entry_cache_write_hits++;
120 #endif
121
122 /* Extended port-specific processing macro, which is by default defined to white space. */
123
8/8
✓ Branch 2 → 3 taken 29967 times.
✓ Branch 2 → 5 taken 11189592 times.
✓ Branch 3 → 4 taken 100 times.
✓ Branch 3 → 5 taken 29867 times.
✓ Branch 12 → 13 taken 24168 times.
✓ Branch 12 → 15 taken 97479890 times.
✓ Branch 13 → 14 taken 108 times.
✓ Branch 13 → 15 taken 24060 times.
108723617 FX_UTILITY_FAT_ENTRY_WRITE_EXTENSION
124
125 /* Calculate the area of the cache for this FAT entry. */
126 108723409 index = (cluster & FX_FAT_CACHE_HASH_MASK) * FX_FAT_CACHE_DEPTH;
127
128 /* Build a pointer to the cache entry. */
129 108723409 cache_entry_ptr = &media_ptr -> fx_media_fat_cache[index];
130
131 /* First search for the entry in the FAT entry cache. */
132
4/4
✓ Branch 12 → 6 taken 33349317 times.
✓ Branch 12 → 13 taken 7086421 times.
✓ Branch 22 → 16 taken 146108993 times.
✓ Branch 22 → 23 taken 13464085 times.
200008816 for (i = 0; i < FX_FAT_CACHE_DEPTH; i++)
133 {
134
135 /* See if the entry matches the write request. */
136
4/4
✓ Branch 6 → 7 taken 4133038 times.
✓ Branch 6 → 11 taken 29216279 times.
✓ Branch 16 → 17 taken 84039865 times.
✓ Branch 16 → 21 taken 62069128 times.
179458310 if (((cache_entry_ptr + i) -> fx_fat_cache_entry_cluster) == cluster)
137 {
138
139 /* Yes, we have a matching entry. Save the new information in the FAT
140 cache and mark this entry as dirty. */
141 88172903 (cache_entry_ptr + i) -> fx_fat_cache_entry_value = next_cluster;
142 88172903 (cache_entry_ptr + i) -> fx_fat_cache_entry_dirty = 1;
143
144 /* Determine if the driver has requested notification when data sectors in the media
145 become free. This can be useful to FLASH manager software. */
146
8/8
✓ Branch 7 → 8 taken 577794 times.
✓ Branch 7 → 10 taken 3555244 times.
✓ Branch 8 → 9 taken 289485 times.
✓ Branch 8 → 10 taken 288309 times.
✓ Branch 17 → 18 taken 767628 times.
✓ Branch 17 → 20 taken 83272237 times.
✓ Branch 18 → 19 taken 384510 times.
✓ Branch 18 → 20 taken 383118 times.
88172903 if ((media_ptr -> fx_media_driver_free_sector_update) && (next_cluster == FX_FREE_CLUSTER))
147 {
148
149 /* Yes, the driver does wish to know that these specific sector(s) are
150 not in use. */
151
152 #ifndef FX_MEDIA_STATISTICS_DISABLE
153
154 /* Increment the number of driver release sectors requests. */
155 673995 media_ptr -> fx_media_driver_release_sectors_requests++;
156 #endif
157
158 /* This cluster is being released so inform the driver that the
159 corresponding sectors are now available. */
160 673995 media_ptr -> fx_media_driver_request = FX_DRIVER_RELEASE_SECTORS;
161 673995 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
162 673995 media_ptr -> fx_media_driver_logical_sector = (media_ptr -> fx_media_data_sector_start +
163 673995 ((cluster - FX_FAT_ENTRY_START) * media_ptr -> fx_media_sectors_per_cluster));
164 673995 media_ptr -> fx_media_driver_sectors = media_ptr -> fx_media_sectors_per_cluster;
165
166 /* If trace is enabled, insert this event into the trace buffer. */
167 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_RELEASE_SECTORS, media_ptr, media_ptr -> fx_media_driver_logical_sector, media_ptr -> fx_media_driver_sectors, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
168
169 /* Call the driver. */
170 673995 (media_ptr -> fx_media_driver_entry)(media_ptr);
171 }
172
173 /* Done, return successful status. */
174 88172903 return(FX_SUCCESS);
175 }
176 }
177
178 /* If we reach this point, we know that the FAT write request is not in
179 the cache. */
180
181 #ifndef FX_MEDIA_STATISTICS_DISABLE
182 /* Decrement the number of cache hits. */
183 20550506 media_ptr -> fx_media_fat_entry_cache_write_hits--;
184
185 /* Increment the number of cache misses. */
186 20550506 media_ptr -> fx_media_fat_entry_cache_write_misses++;
187 #endif
188
189 /* Determine if the oldest entry is dirty and needs to be flushed. */
190
4/4
✓ Branch 13 → 14 taken 265615 times.
✓ Branch 13 → 17 taken 6820806 times.
✓ Branch 23 → 24 taken 390758 times.
✓ Branch 23 → 27 taken 13073327 times.
20550506 if (media_ptr -> fx_media_fat_cache[index + 3].fx_fat_cache_entry_dirty == 1)
191 {
192
193 /* Flush the dirty entry so it can be used to hold the current
194 FAT entry write request. */
195 656373 status = _fx_utility_FAT_flush(media_ptr);
196
197 /* Determine if the write was successful. */
198
4/4
✓ Branch 15 → 16 taken 142230 times.
✓ Branch 15 → 17 taken 123385 times.
✓ Branch 25 → 26 taken 243282 times.
✓ Branch 25 → 27 taken 147476 times.
656373 if (status != FX_SUCCESS)
199 {
200
201 /* No, return error status to caller. */
202 385512 return(status);
203 }
204
205 }
206
207 /* Move all the cache entries down so the oldest is at the bottom. */
208 20164994 *(cache_entry_ptr + 3) = *(cache_entry_ptr + 2);
209 20164994 *(cache_entry_ptr + 2) = *(cache_entry_ptr + 1);
210 20164994 *(cache_entry_ptr + 1) = *(cache_entry_ptr);
211
212 /* Save the current FAT entry write request and mark as dirty. */
213 20164994 cache_entry_ptr -> fx_fat_cache_entry_dirty = 1;
214 20164994 cache_entry_ptr -> fx_fat_cache_entry_cluster = cluster;
215 20164994 cache_entry_ptr -> fx_fat_cache_entry_value = next_cluster;
216
217 /* Determine if the driver has requested notification when data sectors in the media
218 become free. This can be useful to FLASH manager software. */
219
8/8
✓ Branch 17 → 18 taken 361443 times.
✓ Branch 17 → 20 taken 6582748 times.
✓ Branch 18 → 19 taken 199146 times.
✓ Branch 18 → 20 taken 162297 times.
✓ Branch 27 → 28 taken 480682 times.
✓ Branch 27 → 30 taken 12740121 times.
✓ Branch 28 → 29 taken 264650 times.
✓ Branch 28 → 30 taken 216032 times.
20164994 if ((media_ptr -> fx_media_driver_free_sector_update) && (next_cluster == FX_FREE_CLUSTER))
220 {
221
222 /* Yes, the driver does wish to know that these specific sector(s) are
223 not in use. */
224
225 #ifndef FX_MEDIA_STATISTICS_DISABLE
226
227 /* Increment the number of driver release sectors requests. */
228 463796 media_ptr -> fx_media_driver_release_sectors_requests++;
229 #endif
230
231 /* This cluster is being released so inform the driver that the
232 corresponding sectors are now available. */
233 463796 media_ptr -> fx_media_driver_request = FX_DRIVER_RELEASE_SECTORS;
234 463796 media_ptr -> fx_media_driver_status = FX_IO_ERROR;
235 463796 media_ptr -> fx_media_driver_logical_sector = (media_ptr -> fx_media_data_sector_start +
236 463796 ((cluster - FX_FAT_ENTRY_START) * media_ptr -> fx_media_sectors_per_cluster));
237 463796 media_ptr -> fx_media_driver_sectors = media_ptr -> fx_media_sectors_per_cluster;
238
239 /* If trace is enabled, insert this event into the trace buffer. */
240 FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_RELEASE_SECTORS, media_ptr, media_ptr -> fx_media_driver_logical_sector, media_ptr -> fx_media_driver_sectors, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
241
242 /* Call the driver. */
243 463796 (media_ptr -> fx_media_driver_entry)(media_ptr);
244 }
245
246 /* Return success to caller. */
247 20164994 return(FX_SUCCESS);
248 }
249
250