GCC Code Coverage Report


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

fx_file_extended_best_effort_allocate.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 /** File */
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_file.h"
31 #include "fx_utility.h"
32 #include "fx_directory.h"
33 #ifdef FX_ENABLE_FAULT_TOLERANT
34 #include "fx_fault_tolerant.h"
35 #endif /* FX_ENABLE_FAULT_TOLERANT */
36
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _fx_file_extended_best_effort_allocate PORTABLE C */
43 /* 6.1 */
44 /* AUTHOR */
45 /* */
46 /* William E. Lamie, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function attempts to allocate the number of consecutive */
51 /* clusters required to satisfy the user's request. If there are not */
52 /* enough clusters, the largest set of clusters are allocated and */
53 /* linked to the file. If there are no free clusters, an error */
54 /* code is returned to the caller. */
55 /* */
56 /* INPUT */
57 /* */
58 /* file_ptr File control block pointer */
59 /* size Number of bytes to allocate */
60 /* actual_size_allocated Number of bytes allocated */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* return status */
65 /* */
66 /* CALLS */
67 /* */
68 /* _fx_directory_entry_write Update directory entry */
69 /* _fx_utility_FAT_entry_read Read a FAT entry */
70 /* _fx_utility_FAT_entry_write Write a FAT entry */
71 /* _fx_utility_FAT_flush Flush written FAT entries */
72 /* _fx_utility_logical_sector_flush Flush the written log sector */
73 /* _fx_fault_tolerant_transaction_start Start fault tolerant */
74 /* transaction */
75 /* _fx_fault_tolerant_transaction_end End fault tolerant transaction*/
76 /* _fx_fault_tolerant_recover Recover FAT chain */
77 /* _fx_fault_tolerant_reset_log_file Reset the log file */
78 /* _fx_fault_tolerant_set_FAT_chain Set data of FAT chain */
79 /* */
80 /* CALLED BY */
81 /* */
82 /* Application Code */
83 /* */
84 /**************************************************************************/
85 293 UINT _fx_file_extended_best_effort_allocate(FX_FILE *file_ptr, ULONG64 size, ULONG64 *actual_size_allocated)
86 {
87
88 UINT status;
89 ULONG i;
90 UINT found;
91 ULONG bytes_per_cluster;
92 ULONG FAT_index, start_FAT_index;
93 ULONG FAT_value;
94 ULONG clusters, maximum_clusters;
95 FX_MEDIA *media_ptr;
96
97
98 #ifdef TX_ENABLE_EVENT_TRACE
99 TX_TRACE_BUFFER_ENTRY *trace_event;
100 ULONG trace_timestamp;
101 #endif
102
103
104 /* First, determine if the file is still open. */
105
2/2
✓ Branch 2 → 3 taken 18 times.
✓ Branch 2 → 4 taken 275 times.
293 if (file_ptr -> fx_file_id != FX_FILE_ID)
106 {
107
108 /* Return the file not open error status. */
109 18 return(FX_NOT_OPEN);
110 }
111
112 #ifndef FX_MEDIA_STATISTICS_DISABLE
113 /* Setup pointer to media structure. */
114 275 media_ptr = file_ptr -> fx_file_media_ptr;
115
116 /* Increment the number of times this service has been called. */
117 275 media_ptr -> fx_media_file_best_effort_allocates++;
118 #endif
119
120 /* Make sure this file is open for writing. */
121
2/2
✓ Branch 4 → 5 taken 8 times.
✓ Branch 4 → 6 taken 267 times.
275 if (file_ptr -> fx_file_open_mode != FX_OPEN_FOR_WRITE)
122 {
123
124 /* Return the access error exception - a write was attempted from
125 a file opened for reading! */
126 8 return(FX_ACCESS_ERROR);
127 }
128
129 /* Determine if the requested allocation is for zero bytes. */
130
2/2
✓ Branch 6 → 7 taken 8 times.
✓ Branch 6 → 8 taken 259 times.
267 if (size == 0)
131 {
132
133 /* Return a size allocated of zero. */
134 8 *actual_size_allocated = 0;
135
136 /* Return a successful completion - nothing needs to be done. */
137 8 return(FX_SUCCESS);
138 }
139
140 /* Setup pointer to associated media control block. */
141 259 media_ptr = file_ptr -> fx_file_media_ptr;
142
143 /* If trace is enabled, insert this event into the trace buffer. */
144 FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_BEST_EFFORT_ALLOCATE, file_ptr, size, 0, 0, FX_TRACE_FILE_EVENTS, &trace_event, &trace_timestamp)
145
146 /* Protect against other threads accessing the media. */
147 138 FX_PROTECT
148
149 #ifdef FX_ENABLE_FAULT_TOLERANT
150 /* Start transaction. */
151 170 _fx_fault_tolerant_transaction_start(media_ptr);
152 #endif /* FX_ENABLE_FAULT_TOLERANT */
153
154 /* Check for write protect at the media level (set by driver). */
155
6/6
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 10 taken 34 times.
✓ Branch 9 → 10 taken 5 times.
✓ Branch 9 → 12 taken 133 times.
✓ Branch 10 → 11 taken 2 times.
✓ Branch 10 → 14 taken 83 times.
259 if (media_ptr -> fx_media_driver_write_protect)
156 {
157
158 #ifdef FX_ENABLE_FAULT_TOLERANT
159 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
160 #endif /* FX_ENABLE_FAULT_TOLERANT */
161
162 /* Release media protection. */
163 5 FX_UNPROTECT
164
165 /* Return write protect error. */
166 9 return(FX_WRITE_PROTECT);
167 }
168
169 /* Calculate the number of bytes per cluster. */
170 250 bytes_per_cluster = ((ULONG)media_ptr -> fx_media_bytes_per_sector) *
171 250 ((ULONG)media_ptr -> fx_media_sectors_per_cluster);
172
173 /* Check for invalid value. */
174
6/6
✓ Branch 10 → 11 taken 2 times.
✓ Branch 10 → 12 taken 32 times.
✓ Branch 12 → 13 taken 4 times.
✓ Branch 12 → 15 taken 129 times.
✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 18 taken 81 times.
250 if (bytes_per_cluster == 0)
175 {
176
177 #ifdef FX_ENABLE_FAULT_TOLERANT
178 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
179 #endif /* FX_ENABLE_FAULT_TOLERANT */
180
181 /* Release media protection. */
182 4 FX_UNPROTECT
183
184 /* Invalid media, return error. */
185 8 return(FX_MEDIA_INVALID);
186 }
187
188 /* Calculate the number of consecutive clusters needed to satisfy this
189 request. */
190 242 clusters = (ULONG)(((size + bytes_per_cluster - 1) / bytes_per_cluster));
191
192 /* Determine if cluster count is 0. */
193
6/6
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 14 taken 30 times.
✓ Branch 15 → 16 taken 5 times.
✓ Branch 15 → 18 taken 124 times.
✓ Branch 18 → 19 taken 2 times.
✓ Branch 18 → 22 taken 79 times.
242 if (clusters == 0)
194 {
195
196 #ifdef FX_ENABLE_FAULT_TOLERANT
197 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
198 #endif /* FX_ENABLE_FAULT_TOLERANT */
199
200 /* Release media protection. */
201 5 FX_UNPROTECT
202
203 /* Size overflow when rounding to the next cluster, return an error status. */
204 9 return(FX_NO_MORE_SPACE);
205 }
206
207 /* Determine if there are no available clusters on the media. */
208
6/6
✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 16 taken 28 times.
✓ Branch 18 → 19 taken 5 times.
✓ Branch 18 → 21 taken 119 times.
✓ Branch 22 → 23 taken 2 times.
✓ Branch 22 → 26 taken 77 times.
233 if (!media_ptr -> fx_media_available_clusters)
209 {
210
211 #ifdef FX_ENABLE_FAULT_TOLERANT
212 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
213 #endif /* FX_ENABLE_FAULT_TOLERANT */
214
215 /* Release media protection. */
216 5 FX_UNPROTECT
217
218 /* Return a size allocated of zero, since no clusters were available. */
219 9 *actual_size_allocated = 0;
220
221 /* Not enough clusters, return an error status. */
222 9 return(FX_NO_MORE_SPACE);
223 }
224
225 /* Determine if the requested file allocation would exceed the physical limit of the file. */
226
6/6
✓ Branch 16 → 17 taken 26 times.
✓ Branch 16 → 18 taken 2 times.
✓ Branch 21 → 22 taken 114 times.
✓ Branch 21 → 23 taken 5 times.
✓ Branch 26 → 27 taken 75 times.
✓ Branch 26 → 28 taken 2 times.
224 if (((file_ptr -> fx_file_current_available_size + (((ULONG64) clusters) * ((ULONG64) bytes_per_cluster))) < file_ptr -> fx_file_current_available_size) ||
227
6/6
✓ Branch 17 → 18 taken 2 times.
✓ Branch 17 → 19 taken 24 times.
✓ Branch 22 → 23 taken 5 times.
✓ Branch 22 → 25 taken 109 times.
✓ Branch 27 → 28 taken 2 times.
✓ Branch 27 → 31 taken 73 times.
215 ((file_ptr -> fx_file_current_available_size + (((ULONG64) clusters) * ((ULONG64) bytes_per_cluster))) > 0xFFFFFFFFULL))
228 {
229
230 #ifdef FX_ENABLE_FAULT_TOLERANT
231 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
232 #endif /* FX_ENABLE_FAULT_TOLERANT */
233
234 /* Release media protection. */
235 10 FX_UNPROTECT
236
237 /* Return the no more space error, since the new file size would be larger than
238 the 32-bit field to represent it in the file's directory entry. */
239 18 return(FX_NO_MORE_SPACE);
240 }
241
242 /* Now we need to find the consecutive clusters. */
243 206 found = FX_FALSE;
244 206 FAT_index = FX_FAT_ENTRY_START;
245 206 maximum_clusters = 0;
246 206 start_FAT_index = FAT_index;
247
248
6/6
✓ Branch 34 → 20 taken 14324 times.
✓ Branch 34 → 35 taken 4 times.
✓ Branch 41 → 26 taken 36338 times.
✓ Branch 41 → 42 taken 10 times.
✓ Branch 48 → 32 taken 14852 times.
✓ Branch 48 → 49 taken 4 times.
65532 while (FAT_index < (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START))
249 {
250
251 /* Determine if enough consecutive FAT entries are available. */
252 65514 i = 0;
253
254
255 do
256 {
257
258 /* Read a FAT entry. */
259 67963 status = _fx_utility_FAT_entry_read(media_ptr, (FAT_index + i), &FAT_value);
260
261 /* Check for a successful status. */
262
6/6
✓ Branch 22 → 23 taken 2 times.
✓ Branch 22 → 24 taken 14852 times.
✓ Branch 28 → 29 taken 5 times.
✓ Branch 28 → 31 taken 37690 times.
✓ Branch 34 → 35 taken 2 times.
✓ Branch 34 → 38 taken 15412 times.
67963 if (status != FX_SUCCESS)
263 {
264
265 #ifdef FX_ENABLE_FAULT_TOLERANT
266 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
267 #endif /* FX_ENABLE_FAULT_TOLERANT */
268
269 /* Release media protection. */
270 5 FX_UNPROTECT
271
272 /* Return the error status. */
273 9 return(status);
274 }
275
276 /* Determine if the entry is free. */
277
6/6
✓ Branch 24 → 25 taken 14302 times.
✓ Branch 24 → 26 taken 550 times.
✓ Branch 31 → 32 taken 36234 times.
✓ Branch 31 → 33 taken 1456 times.
✓ Branch 38 → 39 taken 14781 times.
✓ Branch 38 → 40 taken 631 times.
67954 if (FAT_value != FX_FREE_CLUSTER)
278 {
279 65317 break;
280 }
281
282 /* Otherwise, increment the consecutive FAT indices. */
283 2637 i++;
284
12/12
✓ Branch 26 → 27 taken 532 times.
✓ Branch 26 → 29 taken 18 times.
✓ Branch 27 → 28 taken 530 times.
✓ Branch 27 → 29 taken 2 times.
✓ Branch 33 → 34 taken 1362 times.
✓ Branch 33 → 36 taken 94 times.
✓ Branch 34 → 35 taken 1357 times.
✓ Branch 34 → 36 taken 5 times.
✓ Branch 40 → 41 taken 564 times.
✓ Branch 40 → 43 taken 67 times.
✓ Branch 41 → 42 taken 562 times.
✓ Branch 41 → 43 taken 2 times.
2637 } while ((i < clusters) && ((FAT_index + i) < media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START));
285
286 /* Determine if a new maximum number of clusters has been found. */
287
6/6
✓ Branch 29 → 30 taken 22 times.
✓ Branch 29 → 31 taken 14300 times.
✓ Branch 36 → 37 taken 104 times.
✓ Branch 36 → 38 taken 36229 times.
✓ Branch 43 → 44 taken 71 times.
✓ Branch 43 → 45 taken 14779 times.
65505 if (i > maximum_clusters)
288 {
289
290 /* Yes, remember the maximum number of clusters and the starting
291 cluster. */
292 197 maximum_clusters = i;
293 197 start_FAT_index = FAT_index;
294 }
295
296 /* Determine if we found enough FAT entries. */
297
6/6
✓ Branch 31 → 32 taken 18 times.
✓ Branch 31 → 33 taken 14304 times.
✓ Branch 38 → 39 taken 94 times.
✓ Branch 38 → 40 taken 36239 times.
✓ Branch 45 → 46 taken 67 times.
✓ Branch 45 → 47 taken 14783 times.
65505 if (i >= clusters)
298 {
299
300 /* Yes, we have found enough FAT entries - set the found
301 flag and get out of this loop. */
302 179 found = FX_TRUE;
303 179 break;
304 }
305 else
306 {
307
308 /* Position to the next possibly free FAT entry. */
309 65326 FAT_index = FAT_index + i + 1;
310 }
311 }
312
313 /* Determine if the total request could not be satisfied, but a partial allocation
314 could be satisfied. */
315
6/6
✓ Branch 35 → 36 taken 20 times.
✓ Branch 35 → 37 taken 2 times.
✓ Branch 42 → 43 taken 99 times.
✓ Branch 42 → 44 taken 5 times.
✓ Branch 49 → 50 taken 69 times.
✓ Branch 49 → 51 taken 2 times.
197 if (maximum_clusters)
316 {
317
318 /* Yes, there was at least one cluster. Prepare to return this
319 to the caller. */
320 188 FAT_index = start_FAT_index;
321 188 clusters = maximum_clusters;
322 188 found = FX_TRUE;
323 }
324
325 /* Determine if we found enough consecutive clusters to satisfy the
326 request. */
327
7/7
✓ Branch 37 → 38 taken 20 times.
✓ Branch 37 → 58 taken 2 times.
✓ Branch 44 → 45 taken 99 times.
✓ Branch 44 → 69 taken 3 times.
✓ Branch 44 → 76 taken 2 times.
✓ Branch 51 → 52 taken 69 times.
✓ Branch 51 → 87 taken 2 times.
197 if (found)
328 {
329
330 #ifdef FX_ENABLE_FAULT_TOLERANT
331
4/4
✓ Branch 45 → 46 taken 51 times.
✓ Branch 45 → 47 taken 18 times.
✓ Branch 52 → 53 taken 51 times.
✓ Branch 52 → 54 taken 18 times.
138 if (media_ptr -> fx_media_fault_tolerant_enabled)
332 {
333
334 /* Record the FAT chain being applied to the file system. This information aids
335 recovery effort if fault happens. */
336 102 media_ptr -> fx_media_fault_tolerant_state |= FX_FAULT_TOLERANT_STATE_SET_FAT_CHAIN;
337 102 _fx_fault_tolerant_set_FAT_chain(media_ptr, FX_FALSE, file_ptr -> fx_file_last_physical_cluster,
338 FAT_index, media_ptr -> fx_media_fat_last, media_ptr -> fx_media_fat_last);
339 }
340 #endif /* FX_ENABLE_FAULT_TOLERANT */
341
342
343 /* Update the link pointers in the new clusters. */
344
8/8
✓ Branch 43 → 39 taken 524 times.
✓ Branch 43 → 44 taken 18 times.
✓ Branch 51 → 46 taken 786 times.
✓ Branch 51 → 52 taken 27 times.
✓ Branch 53 → 48 taken 556 times.
✓ Branch 53 → 54 taken 61 times.
✓ Branch 61 → 55 taken 556 times.
✓ Branch 61 → 62 taken 61 times.
2589 for (i = 0; i < (clusters - 1); i++)
345 {
346
347 /* Update the cluster links. Since the allocation is
348 sequential, we just have to link each FAT entry to the
349 next one. */
350 2422 status = _fx_utility_FAT_entry_write(media_ptr, FAT_index + i, FAT_index + i + 1);
351
352 /* Check for a bad status. */
353
8/8
✓ Branch 40 → 41 taken 2 times.
✓ Branch 40 → 42 taken 522 times.
✓ Branch 47 → 48 taken 3 times.
✓ Branch 47 → 50 taken 783 times.
✓ Branch 49 → 50 taken 2 times.
✓ Branch 49 → 52 taken 554 times.
✓ Branch 56 → 57 taken 2 times.
✓ Branch 56 → 60 taken 554 times.
2422 if (status != FX_SUCCESS)
354 {
355
356 #ifdef FX_ENABLE_FAULT_TOLERANT
357 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
358 #endif /* FX_ENABLE_FAULT_TOLERANT */
359
360 /* Release media protection. */
361 5 FX_UNPROTECT
362
363 /* Return the error status. */
364 9 return(status);
365 }
366 }
367
368
369 /* Now place an EOF in the last cluster entry. */
370 167 status = _fx_utility_FAT_entry_write(media_ptr, FAT_index + clusters - 1, media_ptr -> fx_media_fat_last);
371
372 /* Check for a bad status. */
373
8/8
✓ Branch 45 → 46 taken 2 times.
✓ Branch 45 → 47 taken 16 times.
✓ Branch 53 → 54 taken 3 times.
✓ Branch 53 → 56 taken 24 times.
✓ Branch 55 → 56 taken 2 times.
✓ Branch 55 → 58 taken 59 times.
✓ Branch 63 → 64 taken 2 times.
✓ Branch 63 → 67 taken 59 times.
167 if (status != FX_SUCCESS)
374 {
375
376 #ifdef FX_ENABLE_FAULT_TOLERANT
377 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
378 #endif /* FX_ENABLE_FAULT_TOLERANT */
379
380 /* Release media protection. */
381 5 FX_UNPROTECT
382
383 /* Return the error status. */
384 9 return(status);
385 }
386
387 #ifdef FX_FAULT_TOLERANT
388
389 /* Flush the cached individual FAT entries */
390 118 _fx_utility_FAT_flush(media_ptr);
391 #endif
392
393 /* Actually link up the new clusters to the file. */
394
395 /* Determine if there are already clusters allocated for this file. */
396
8/8
✓ Branch 47 → 48 taken 12 times.
✓ Branch 47 → 54 taken 4 times.
✓ Branch 56 → 57 taken 18 times.
✓ Branch 56 → 64 taken 6 times.
✓ Branch 59 → 60 taken 27 times.
✓ Branch 59 → 67 taken 24 times.
✓ Branch 68 → 69 taken 27 times.
✓ Branch 68 → 77 taken 24 times.
142 if (file_ptr -> fx_file_total_clusters)
397 {
398
399
400 /* Linkup the last cluster. */
401 84 status = _fx_utility_FAT_entry_write(media_ptr,
402 file_ptr -> fx_file_last_physical_cluster, FAT_index);
403
404 /* Check for a bad status. */
405
8/8
✓ Branch 49 → 50 taken 2 times.
✓ Branch 49 → 51 taken 10 times.
✓ Branch 58 → 59 taken 3 times.
✓ Branch 58 → 61 taken 15 times.
✓ Branch 61 → 62 taken 2 times.
✓ Branch 61 → 64 taken 25 times.
✓ Branch 70 → 71 taken 2 times.
✓ Branch 70 → 74 taken 25 times.
84 if (status != FX_SUCCESS)
406 {
407
408 #ifdef FX_ENABLE_FAULT_TOLERANT
409 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
410 #endif /* FX_ENABLE_FAULT_TOLERANT */
411
412 /* Release media protection. */
413 5 FX_UNPROTECT
414
415 /* Return the error status. */
416 9 return(status);
417 }
418
419 /* Determine if we are adding a sector after a write filled the previously
420 allocated cluster exactly. */
421 75 if ((file_ptr -> fx_file_current_relative_sector >=
422
8/8
✓ Branch 51 → 52 taken 8 times.
✓ Branch 51 → 55 taken 2 times.
✓ Branch 61 → 62 taken 12 times.
✓ Branch 61 → 65 taken 3 times.
✓ Branch 64 → 65 taken 8 times.
✓ Branch 64 → 69 taken 17 times.
✓ Branch 74 → 75 taken 8 times.
✓ Branch 74 → 79 taken 17 times.
75 (media_ptr -> fx_media_sectors_per_cluster - 1)) &&
423 36 (file_ptr -> fx_file_current_logical_offset >=
424
8/8
✓ Branch 52 → 53 taken 4 times.
✓ Branch 52 → 55 taken 4 times.
✓ Branch 62 → 63 taken 6 times.
✓ Branch 62 → 65 taken 6 times.
✓ Branch 65 → 66 taken 4 times.
✓ Branch 65 → 69 taken 4 times.
✓ Branch 75 → 76 taken 4 times.
✓ Branch 75 → 79 taken 4 times.
36 media_ptr -> fx_media_bytes_per_sector))
425 {
426
427 /* Yes, we need to adjust all of the pertinent file parameters for
428 access into this newly allocated cluster. */
429 18 file_ptr -> fx_file_current_physical_cluster = FAT_index;
430 18 file_ptr -> fx_file_current_relative_cluster++;
431 18 file_ptr -> fx_file_current_relative_sector = 0;
432 18 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
433 18 (((ULONG64)(FAT_index - FX_FAT_ENTRY_START)) *
434 18 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
435 18 file_ptr -> fx_file_current_logical_offset = 0;
436 }
437 }
438 else
439 {
440
441 /* These new clusters are also the first! Setup the initial
442 file parameters. */
443 58 file_ptr -> fx_file_first_physical_cluster = FAT_index;
444 58 file_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster;
445 58 file_ptr -> fx_file_current_relative_cluster = 0;
446 58 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
447 58 (((ULONG64)(file_ptr -> fx_file_first_physical_cluster - FX_FAT_ENTRY_START)) *
448 58 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
449 58 file_ptr -> fx_file_current_logical_offset = 0;
450 58 file_ptr -> fx_file_current_file_offset = 0;
451
452 /* Setup the consecutive clusters at the beginning of the file. */
453 58 file_ptr -> fx_file_consecutive_cluster = clusters;
454
455 /* Update the first cluster in the directory entry. */
456 58 file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster = FAT_index;
457
458 #ifdef FX_ENABLE_FAULT_TOLERANT
459
4/4
✓ Branch 67 → 68 taken 22 times.
✓ Branch 67 → 69 taken 2 times.
✓ Branch 77 → 78 taken 22 times.
✓ Branch 77 → 79 taken 2 times.
48 if (media_ptr -> fx_media_fault_tolerant_enabled)
460 {
461
462 /* Clear undo phase. */
463 44 media_ptr -> fx_media_fault_tolerant_state &= (UCHAR)(~FX_FAULT_TOLERANT_STATE_SET_FAT_CHAIN & 0xff);
464 }
465 #endif /* FX_ENABLE_FAULT_TOLERANT */
466 }
467
468 /* Remember the last physical cluster. */
469 133 file_ptr -> fx_file_last_physical_cluster = FAT_index + clusters - 1;
470
471 /* Update the available size. */
472
473 /* Normal condition, update the available size. */
474 133 file_ptr -> fx_file_current_available_size =
475 133 file_ptr -> fx_file_current_available_size + bytes_per_cluster * clusters;
476
477 /* Increment the total clusters for this file. */
478 133 file_ptr -> fx_file_total_clusters =
479 133 file_ptr -> fx_file_total_clusters + clusters;
480
481 /* Decrease the available clusters on the media. */
482 133 media_ptr -> fx_media_available_clusters =
483 133 media_ptr -> fx_media_available_clusters - clusters;
484
485 /* Return the actual size allocated. */
486 133 *actual_size_allocated = ((ULONG64)clusters) * bytes_per_cluster;
487
488 #if defined(FX_UPDATE_FILE_SIZE_ON_ALLOCATE) || defined(FX_ENABLE_FAULT_TOLERANT)
489
490 /* Set the file size the current size plus what what was added. */
491
4/4
✓ Branch 69 → 70 taken 16 times.
✓ Branch 69 → 71 taken 33 times.
✓ Branch 79 → 80 taken 16 times.
✓ Branch 79 → 81 taken 33 times.
98 if (size < *actual_size_allocated)
492 {
493 32 file_ptr -> fx_file_current_file_size += size;
494 }
495 else
496 {
497 66 file_ptr -> fx_file_current_file_size += *actual_size_allocated;
498 }
499
500 /* Copy the new file size into the directory entry. */
501 98 file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size = file_ptr -> fx_file_current_file_size;
502 #endif
503
504 /* Update the trace event with the bytes allocated. */
505 FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_FILE_BEST_EFFORT_ALLOCATE, 0, 0, *actual_size_allocated, 0);
506
507 /* Write the directory entry to the media. */
508 133 status = _fx_directory_entry_write(media_ptr, &(file_ptr -> fx_file_dir_entry));
509
510 /* Check for a good status. */
511
8/8
✓ Branch 56 → 57 taken 2 times.
✓ Branch 56 → 59 taken 12 times.
✓ Branch 66 → 67 taken 3 times.
✓ Branch 66 → 71 taken 18 times.
✓ Branch 73 → 74 taken 2 times.
✓ Branch 73 → 78 taken 47 times.
✓ Branch 83 → 84 taken 2 times.
✓ Branch 83 → 90 taken 47 times.
133 if (status != FX_SUCCESS)
512 {
513
514 #ifdef FX_ENABLE_FAULT_TOLERANT
515 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
516 #endif /* FX_ENABLE_FAULT_TOLERANT */
517
518 /* Release media protection. */
519 5 FX_UNPROTECT
520
521 /* Return the error status. */
522 9 return(status);
523 }
524 }
525 else
526 {
527
528 #ifdef FX_ENABLE_FAULT_TOLERANT
529 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
530 #endif /* FX_ENABLE_FAULT_TOLERANT */
531
532 /* Release media protection. */
533 5 FX_UNPROTECT
534
535 /* Return a size allocated of zero, since no clusters were available. */
536 9 *actual_size_allocated = 0;
537
538 /* Not enough contiguous space on the media. Return error status. */
539 9 return(FX_NO_MORE_SPACE);
540 }
541
542 #ifdef FX_FAULT_TOLERANT
543
544 /* Flush the cached individual FAT entries */
545 94 _fx_utility_FAT_flush(media_ptr);
546 #endif
547
548 /* Flush the internal logical sector cache. */
549 124 status = _fx_utility_logical_sector_flush(media_ptr, ((ULONG64) 1), (ULONG64) (media_ptr -> fx_media_sectors_per_FAT), FX_FALSE);
550
551 #ifdef FX_ENABLE_FAULT_TOLERANT
552 /* Check for a bad status. */
553
4/4
✓ Branch 80 → 81 taken 1 time.
✓ Branch 80 → 83 taken 46 times.
✓ Branch 92 → 93 taken 1 time.
✓ Branch 92 → 96 taken 46 times.
94 if (status != FX_SUCCESS)
554 {
555
556 2 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
557
558 /* Release media protection. */
559 1 FX_UNPROTECT
560
561 /* Return the bad status. */
562 2 return(status);
563 }
564
565 /* End transaction. */
566 92 status = _fx_fault_tolerant_transaction_end(media_ptr);
567 #endif /* FX_ENABLE_FAULT_TOLERANT */
568
569 /* Release media protection. */
570 52 FX_UNPROTECT
571
572 /* Return status to the caller. */
573 98 return(status);
574 }
575
576