GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 99.3% 416 / 0 / 419
Functions: 100.0% 1 / 0 / 1
Branches: 99.7% 630 / 0 / 632

fx_file_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 /** File */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define FX_SOURCE_CODE
24
25 /* Include necessary system files. */
26
27 #include "fx_api.h"
28 #include "fx_system.h"
29 #include "fx_file.h"
30 #include "fx_directory.h"
31 #include "fx_utility.h"
32 #ifdef FX_ENABLE_FAULT_TOLERANT
33 #include "fx_fault_tolerant.h"
34 #endif /* FX_ENABLE_FAULT_TOLERANT */
35
36
37 /**************************************************************************/
38 /* */
39 /* FUNCTION RELEASE */
40 /* */
41 /* _fx_file_write PORTABLE C */
42 /* 6.1 */
43 /* AUTHOR */
44 /* */
45 /* William E. Lamie, Microsoft Corporation */
46 /* */
47 /* DESCRIPTION */
48 /* */
49 /* This function writes the specified number of bytes into the file's */
50 /* data area. The status of the write operation is returned to the */
51 /* caller. In addition, various internal file pointers in the file */
52 /* control block are also updated. */
53 /* */
54 /* INPUT */
55 /* */
56 /* file_ptr File control block pointer */
57 /* buffer_ptr Buffer pointer */
58 /* size Number of bytes to write */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* return status */
63 /* */
64 /* CALLS */
65 /* */
66 /* _fx_directory_entry_write Update the file's size */
67 /* _fx_utility_FAT_entry_read Read a FAT entry */
68 /* _fx_utility_FAT_entry_write Write a FAT entry */
69 /* _fx_utility_FAT_flush Flush written FAT entries */
70 /* _fx_utility_logical_sector_flush Flush written logical sectors */
71 /* _fx_utility_logical_sector_read Read a logical sector */
72 /* _fx_utility_logical_sector_write Write a logical sector */
73 /* _fx_utility_memory_copy Fast memory copy routine */
74 /* _fx_fault_tolerant_transaction_start Start fault tolerant */
75 /* transaction */
76 /* _fx_fault_tolerant_transaction_end End fault tolerant transaction*/
77 /* _fx_fault_tolerant_recover Recover FAT chain */
78 /* _fx_fault_tolerant_reset_log_file Reset the log file */
79 /* _fx_fault_tolerant_set_FAT_chain Set data of FAT chain */
80 /* */
81 /* CALLED BY */
82 /* */
83 /* Application Code */
84 /* */
85 /**************************************************************************/
86 162244155 UINT _fx_file_write(FX_FILE *file_ptr, VOID *buffer_ptr, ULONG size)
87 {
88
89 UINT status;
90 ULONG64 bytes_remaining;
91 ULONG i;
92 ULONG copy_bytes;
93 ULONG bytes_per_cluster;
94 UCHAR *source_ptr;
95 ULONG first_new_cluster;
96 ULONG last_cluster;
97 ULONG cluster, next_cluster;
98 ULONG FAT_index;
99 ULONG FAT_value;
100 ULONG clusters;
101 ULONG total_clusters;
102 UINT sectors;
103 FX_MEDIA *media_ptr;
104
105
106 #ifdef FX_FAULT_TOLERANT_DATA
107 FX_INT_SAVE_AREA
108 #endif
109
110 #ifndef FX_DONT_UPDATE_OPEN_FILES
111 ULONG open_count;
112 FX_FILE *search_ptr;
113 #endif
114
115 #ifdef TX_ENABLE_EVENT_TRACE
116 TX_TRACE_BUFFER_ENTRY *trace_event;
117 ULONG trace_timestamp;
118 #endif
119
120 #ifdef FX_ENABLE_FAULT_TOLERANT
121 159195211 UCHAR data_append = FX_FALSE; /* Whether or not new data would extend beyond the size of the original file.
122 Operations such as append or overwrite could cause the new file to exceed its
123 original size, resulting in data-appending operation. */
124 159195211 ULONG copy_head_cluster = 0; /* The first cluster of the original chain that needs to be replaced. */
125 159195211 ULONG copy_tail_cluster = 0; /* The last cluster of the original chain that needs to be replaced. */
126 ULONG insertion_back; /* The insertion point (back) */
127 159195211 ULONG insertion_front = 0; /* The insertion point (front) */
128 159195211 ULONG replace_clusters = 0; /* The number of clusters to be replaced. */
129 #endif /* FX_ENABLE_FAULT_TOLERANT */
130
131
132 /* First, determine if the file is still open. */
133
2/2
✓ Branch 2 → 3 taken 13 times.
✓ Branch 2 → 4 taken 162244142 times.
162244155 if (file_ptr -> fx_file_id != FX_FILE_ID)
134 {
135
136 /* Return the file not open error status. */
137 13 return(FX_NOT_OPEN);
138 }
139
140 /* Setup pointer to media structure. */
141 162244142 media_ptr = file_ptr -> fx_file_media_ptr;
142
143 #ifndef FX_MEDIA_STATISTICS_DISABLE
144
145 /* Increment the number of times this service has been called. */
146 162244142 media_ptr -> fx_media_file_writes++;
147 #endif
148
149
150
2/2
✓ Branch 4 → 5 taken 9 times.
✓ Branch 4 → 6 taken 162244133 times.
162244142 if (file_ptr -> fx_file_current_file_offset + size > 0xFFFFFFFFULL)
151 {
152
153 /* Return the no more space error, since the new file size would be larger than
154 the 32-bit field to represent it in the file's directory entry. */
155 9 return(FX_NO_MORE_SPACE);
156 }
157
158 #ifdef FX_ENABLE_FAULT_TOLERANT
159 /* Initialize next cluster of tail. */
160 159195199 insertion_back = media_ptr -> fx_media_fat_last;
161 #endif /* FX_ENABLE_FAULT_TOLERANT */
162
163 /* If trace is enabled, insert this event into the trace buffer. */
164 FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_WRITE, file_ptr, buffer_ptr, size, 0, FX_TRACE_FILE_EVENTS, &trace_event, &trace_timestamp)
165
166 /* Protect against other threads accessing the media. */
167 83122178 FX_PROTECT
168
169 /* Check for write protect at the media level (set by driver). */
170
4/4
✓ Branch 6 → 7 taken 4 times.
✓ Branch 6 → 8 taken 79121951 times.
✓ Branch 7 → 8 taken 5 times.
✓ Branch 7 → 10 taken 83122173 times.
162244133 if (media_ptr -> fx_media_driver_write_protect)
171 {
172
173 /* Release media protection. */
174 5 FX_UNPROTECT
175
176 /* Return write protect error. */
177 9 return(FX_WRITE_PROTECT);
178 }
179
180 /* Make sure this file is open for writing. */
181
4/4
✓ Branch 8 → 9 taken 4 times.
✓ Branch 8 → 10 taken 79121947 times.
✓ Branch 10 → 11 taken 5 times.
✓ Branch 10 → 13 taken 83122168 times.
162244124 if (file_ptr -> fx_file_open_mode != FX_OPEN_FOR_WRITE)
182 {
183
184 /* Release media protection. */
185 5 FX_UNPROTECT
186
187 /* Return the access error exception - a write was attempted from
188 a file opened for reading! */
189 9 return(FX_ACCESS_ERROR);
190 }
191
192 #ifdef FX_ENABLE_FAULT_TOLERANT
193
194 /* Start transaction. */
195 159195191 _fx_fault_tolerant_transaction_start(media_ptr);
196 #endif /* FX_ENABLE_FAULT_TOLERANT */
197
198 /* Calculate the number of bytes per cluster. */
199 162244115 bytes_per_cluster = ((ULONG)media_ptr -> fx_media_bytes_per_sector) *
200 162244115 ((ULONG)media_ptr -> fx_media_sectors_per_cluster);
201
202 /* Check for invalid value. */
203
8/8
✓ Branch 10 → 11 taken 2 times.
✓ Branch 10 → 12 taken 1224579 times.
✓ Branch 11 → 12 taken 2 times.
✓ Branch 11 → 14 taken 77897364 times.
✓ Branch 13 → 14 taken 3 times.
✓ Branch 13 → 16 taken 1824340 times.
✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 18 taken 81297823 times.
162244115 if (bytes_per_cluster == 0)
204 {
205
206 #ifdef FX_ENABLE_FAULT_TOLERANT
207 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
208 #endif /* FX_ENABLE_FAULT_TOLERANT */
209
210 /* Release media protection. */
211 5 FX_UNPROTECT
212
213 /* Invalid media, return error. */
214 9 return(FX_MEDIA_INVALID);
215 }
216
217 /* Initialized first new cluster. */
218 162244106 first_new_cluster = 0;
219
220 #ifdef FX_ENABLE_FAULT_TOLERANT
221 /* Calculate clusters need to be replaced when fault tolerant is enabled. */
222
4/4
✓ Branch 14 → 15 taken 76667858 times.
✓ Branch 14 → 25 taken 1229506 times.
✓ Branch 18 → 19 taken 80068317 times.
✓ Branch 18 → 29 taken 1229506 times.
159195187 if (media_ptr -> fx_media_fault_tolerant_enabled)
223 {
224
225
4/4
✓ Branch 15 → 16 taken 75861334 times.
✓ Branch 15 → 17 taken 806524 times.
✓ Branch 19 → 20 taken 79261793 times.
✓ Branch 19 → 21 taken 806524 times.
156736175 if (file_ptr -> fx_file_current_file_offset == file_ptr -> fx_file_current_file_size)
226 {
227
228 /* Appending data. No need to replace existing clusters. */
229 155123127 replace_clusters = 0;
230 }
231
4/4
✓ Branch 17 → 18 taken 36 times.
✓ Branch 17 → 19 taken 806488 times.
✓ Branch 21 → 22 taken 36 times.
✓ Branch 21 → 23 taken 806488 times.
1613048 else if (file_ptr -> fx_file_current_file_offset == file_ptr -> fx_file_maximum_size_used)
232 {
233
234 /* Similar to append data. No actual data after fx_file_maximum_size_used.
235 * No need to replace existing clusters. */
236 72 replace_clusters = 0;
237 }
238 1612976 else if (((file_ptr -> fx_file_current_file_offset / media_ptr -> fx_media_bytes_per_sector) ==
239
4/4
✓ Branch 19 → 20 taken 150100 times.
✓ Branch 19 → 22 taken 656388 times.
✓ Branch 23 → 24 taken 149590 times.
✓ Branch 23 → 26 taken 656898 times.
1612976 ((file_ptr -> fx_file_current_file_offset + size - 1) / media_ptr -> fx_media_bytes_per_sector)) &&
240
4/4
✓ Branch 20 → 21 taken 150080 times.
✓ Branch 20 → 22 taken 20 times.
✓ Branch 24 → 25 taken 149570 times.
✓ Branch 24 → 26 taken 20 times.
299690 ((file_ptr -> fx_file_current_file_offset + size) <= file_ptr -> fx_file_current_file_size))
241 {
242
243 /* Overwriting data in one sector. No need to replace existing clusters. */
244 299650 replace_clusters = 0;
245 }
246
4/4
✓ Branch 22 → 23 taken 200 times.
✓ Branch 22 → 24 taken 656208 times.
✓ Branch 26 → 27 taken 200 times.
✓ Branch 26 → 28 taken 656718 times.
1313326 else if ((file_ptr -> fx_file_current_available_size - file_ptr -> fx_file_current_file_offset) < size)
247 {
248
249 /* Replace all clusters from current_cluster. */
250 400 replace_clusters = (UINT)(file_ptr -> fx_file_total_clusters - file_ptr -> fx_file_current_relative_cluster);
251 400 copy_head_cluster = file_ptr -> fx_file_current_physical_cluster;
252
253 400 data_append = FX_TRUE;
254 }
255 else
256 {
257
258 /* Replace clusters from current_cluster to the end of written cluster. */
259 1312926 replace_clusters = (UINT)((file_ptr -> fx_file_current_file_offset + size + bytes_per_cluster - 1) / bytes_per_cluster -
260 1312926 file_ptr -> fx_file_current_relative_cluster);
261 1312926 copy_head_cluster = file_ptr -> fx_file_current_physical_cluster;
262 1312926 data_append = FX_FALSE;
263 }
264 }
265 #endif /* FX_ENABLE_FAULT_TOLERANT */
266
267 /* Next, determine if there is enough room to write the specified number of
268 bytes to the clusters already allocated to this file. */
269
8/8
✓ Branch 12 → 13 taken 118074 times.
✓ Branch 12 → 53 taken 1106505 times.
✓ Branch 16 → 17 taken 177356 times.
✓ Branch 16 → 63 taken 1646984 times.
✓ Branch 25 → 26 taken 77629583 times.
✓ Branch 25 → 27 taken 267781 times.
✓ Branch 29 → 30 taken 77629583 times.
✓ Branch 29 → 31 taken 3668240 times.
162244106 if (((file_ptr -> fx_file_current_available_size - file_ptr -> fx_file_current_file_offset) < size)
270 #ifdef FX_ENABLE_FAULT_TOLERANT
271
4/4
✓ Branch 26 → 27 taken 656208 times.
✓ Branch 26 → 139 taken 76973375 times.
✓ Branch 30 → 31 taken 656717 times.
✓ Branch 30 → 154 taken 76972866 times.
155259166 || (replace_clusters)
272 #endif /* FX_ENABLE_FAULT_TOLERANT */
273 )
274 {
275
276 /* The new request will not fit within the currently allocated clusters. */
277
278 /* Calculate the number of additional clusters that must be allocated for this
279 write request. */
280 #ifdef FX_ENABLE_FAULT_TOLERANT
281 /* Find the number of clusters that need to be replaced. */
282
4/4
✓ Branch 27 → 28 taken 805936 times.
✓ Branch 27 → 68 taken 118053 times.
✓ Branch 31 → 32 taken 4206904 times.
✓ Branch 31 → 76 taken 118053 times.
5248946 if (media_ptr -> fx_media_fault_tolerant_enabled)
283 {
284
285 /* Mark the recovery phase. */
286 5012840 media_ptr -> fx_media_fault_tolerant_state |= FX_FAULT_TOLERANT_STATE_SET_FAT_CHAIN;
287
288 5012840 bytes_remaining = file_ptr -> fx_file_current_file_offset + size;
289
290
4/4
✓ Branch 28 → 29 taken 656406 times.
✓ Branch 28 → 67 taken 149530 times.
✓ Branch 32 → 33 taken 656915 times.
✓ Branch 32 → 75 taken 3549989 times.
5012840 if (replace_clusters > 0)
291 {
292
293
294 /* Find previous cluster of copy head cluster. */
295 /* The previous cluster is not initialized. Find it. */
296
4/4
✓ Branch 29 → 30 taken 494493 times.
✓ Branch 29 → 47 taken 161913 times.
✓ Branch 33 → 34 taken 494479 times.
✓ Branch 33 → 53 taken 162436 times.
1313321 if (copy_head_cluster != file_ptr -> fx_file_first_physical_cluster)
297 {
298
299 /* The copy head cluster is not the first cluster of file. */
300 /* Copy head is not the first cluster of file. */
301
4/4
✓ Branch 30 → 31 taken 6 times.
✓ Branch 30 → 32 taken 494487 times.
✓ Branch 34 → 35 taken 6 times.
✓ Branch 34 → 36 taken 494473 times.
988972 if (file_ptr -> fx_file_current_relative_cluster < file_ptr -> fx_file_consecutive_cluster)
302 {
303
304 /* Clusters before current cluster are consecutive. */
305 12 insertion_front = copy_head_cluster - 1;
306 12 bytes_remaining -= file_ptr -> fx_file_current_relative_cluster * bytes_per_cluster;
307 }
308 else
309 {
310
311 /* Skip consecutive clusters first. */
312 988960 cluster = file_ptr -> fx_file_first_physical_cluster;
313
314 /* Loop the link of FAT to find the previous cluster. */
315
8/8
✓ Branch 40 → 41 taken 1122485 times.
✓ Branch 40 → 42 taken 4 times.
✓ Branch 41 → 33 taken 1122479 times.
✓ Branch 41 → 42 taken 6 times.
✓ Branch 45 → 46 taken 1121794 times.
✓ Branch 45 → 47 taken 4 times.
✓ Branch 46 → 37 taken 1121788 times.
✓ Branch 46 → 47 taken 6 times.
2244287 while ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved))
316 {
317
318 /* Reduce remaining bytes. */
319 2244267 bytes_remaining -= bytes_per_cluster;
320
321 /* Read the current cluster entry from the FAT. */
322 2244267 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &FAT_value);
323
324 /* Check the return value. */
325
4/4
✓ Branch 34 → 35 taken 8 times.
✓ Branch 34 → 37 taken 1122471 times.
✓ Branch 38 → 39 taken 8 times.
✓ Branch 38 → 42 taken 1121780 times.
2244267 if (status != FX_SUCCESS)
326 {
327
328 16 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
329
330 /* Release media protection. */
331 8 FX_UNPROTECT
332
333 /* Return the error status. */
334 16 return(status);
335 }
336
337
4/4
✓ Branch 37 → 38 taken 494469 times.
✓ Branch 37 → 39 taken 628002 times.
✓ Branch 42 → 43 taken 494455 times.
✓ Branch 42 → 44 taken 627325 times.
2244251 if (FAT_value == copy_head_cluster)
338 {
339 988924 break;
340 }
341
342 /* Move to next cluster. */
343 1255327 cluster = FAT_value;
344 }
345
346
8/8
✓ Branch 42 → 43 taken 494475 times.
✓ Branch 42 → 45 taken 4 times.
✓ Branch 43 → 44 taken 494469 times.
✓ Branch 43 → 45 taken 6 times.
✓ Branch 47 → 48 taken 494461 times.
✓ Branch 47 → 50 taken 4 times.
✓ Branch 48 → 49 taken 494455 times.
✓ Branch 48 → 50 taken 6 times.
988944 if ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved))
347 {
348
349 /* Find the previous cluster. */
350 988924 insertion_front = cluster;
351 }
352 else
353 {
354
355 20 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
356
357 /* Release media protection. */
358 10 FX_UNPROTECT
359
360 /* Return the error status. */
361 20 return(FX_NOT_FOUND);
362 }
363 }
364 }
365
366 /* Find copy tail cluster. */
367
4/4
✓ Branch 47 → 48 taken 252276 times.
✓ Branch 47 → 49 taken 404112 times.
✓ Branch 53 → 54 taken 251251 times.
✓ Branch 53 → 55 taken 405646 times.
1313285 if (bytes_remaining <= bytes_per_cluster)
368 {
369
370 /* Only one cluster is modified. */
371 503527 copy_tail_cluster = copy_head_cluster;
372 }
373
4/4
✓ Branch 49 → 50 taken 403914 times.
✓ Branch 49 → 61 taken 198 times.
✓ Branch 55 → 56 taken 405448 times.
✓ Branch 55 → 68 taken 198 times.
809758 else if (data_append == FX_FALSE)
374 {
375
376 /* Search from copy head cluster. */
377 809362 cluster = copy_head_cluster;
378 809362 FAT_value = FX_FAT_ENTRY_START;
379
380 /* Loop the link of FAT to find the previous cluster. */
381
8/8
✓ Branch 58 → 59 taken 1019059 times.
✓ Branch 58 → 60 taken 2 times.
✓ Branch 59 → 51 taken 1019057 times.
✓ Branch 59 → 60 taken 2 times.
✓ Branch 65 → 66 taken 1023436 times.
✓ Branch 65 → 67 taken 2 times.
✓ Branch 66 → 57 taken 1023434 times.
✓ Branch 66 → 67 taken 2 times.
2042499 while ((cluster >= FX_FAT_ENTRY_START) && (cluster < media_ptr -> fx_media_fat_reserved))
382 {
383
384
4/4
✓ Branch 51 → 52 taken 403906 times.
✓ Branch 51 → 53 taken 615151 times.
✓ Branch 57 → 58 taken 405440 times.
✓ Branch 57 → 59 taken 617994 times.
2042491 if (bytes_remaining <= bytes_per_cluster)
385 {
386 809346 break;
387 }
388
389 /* Reduce remaining bytes. */
390 1233145 bytes_remaining -= bytes_per_cluster;
391
392 /* Read the current cluster entry from the FAT. */
393 1233145 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &FAT_value);
394
395 /* Check the return value. */
396
4/4
✓ Branch 54 → 55 taken 4 times.
✓ Branch 54 → 57 taken 615147 times.
✓ Branch 60 → 61 taken 4 times.
✓ Branch 60 → 64 taken 617990 times.
1233145 if (status != FX_SUCCESS)
397 {
398
399 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
400
401 /* Release media protection. */
402 4 FX_UNPROTECT
403
404 /* Return the error status. */
405 8 return(status);
406 }
407
408 /* Move to next cluster. */
409 1233137 cluster = FAT_value;
410 }
411
412 /* Find the previous cluster. */
413 809354 copy_tail_cluster = FAT_value;
414 }
415
416 /* Get the cluster next to copy tail. */
417
4/4
✓ Branch 61 → 62 taken 656186 times.
✓ Branch 61 → 66 taken 198 times.
✓ Branch 68 → 69 taken 656695 times.
✓ Branch 68 → 74 taken 198 times.
1313277 if (data_append == FX_FALSE)
418 {
419
420 /* Read FAT entry. */
421 1312881 status = _fx_utility_FAT_entry_read(media_ptr, copy_tail_cluster, &insertion_back);
422
423 /* Check for a bad status. */
424
2/4
✗ Branch 63 → 64 not taken.
✓ Branch 63 → 68 taken 656186 times.
✗ Branch 70 → 71 not taken.
✓ Branch 70 → 76 taken 656695 times.
1312881 if (status != FX_SUCCESS)
425 {
426
427 ✗ FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
428
429 /* Release media protection. */
430 ✗ FX_UNPROTECT
431
432 /* Return the bad status. */
433 ✗ return(status);
434 }
435 }
436 else
437 {
438 396 insertion_back = media_ptr -> fx_media_fat_last;
439 }
440 }
441 else
442 {
443 3699519 insertion_back = media_ptr -> fx_media_fat_last;
444 }
445 }
446
447
4/4
✓ Branch 68 → 69 taken 267781 times.
✓ Branch 68 → 70 taken 656186 times.
✓ Branch 76 → 77 taken 3668240 times.
✓ Branch 76 → 78 taken 656695 times.
5248902 if (file_ptr -> fx_file_current_available_size - file_ptr -> fx_file_current_file_offset < size)
448 {
449 #endif /* FX_ENABLE_FAULT_TOLERANT */
450 /* Calculate clusters that are needed for data append except ones overwritten. */
451 4231451 clusters = (UINT)((size + (bytes_per_cluster - 1) -
452 4231451 (file_ptr -> fx_file_current_available_size - file_ptr -> fx_file_current_file_offset)) /
453 bytes_per_cluster);
454 #ifdef FX_ENABLE_FAULT_TOLERANT
455 }
456 else
457 {
458 1312881 clusters = 0;
459 }
460 #endif /* FX_ENABLE_FAULT_TOLERANT */
461
462 /* Determine if we have enough space left. */
463 #ifdef FX_ENABLE_FAULT_TOLERANT
464
4/4
✓ Branch 71 → 72 taken 4 times.
✓ Branch 71 → 74 taken 923963 times.
✓ Branch 79 → 80 taken 4 times.
✓ Branch 79 → 83 taken 4324931 times.
5248902 if (clusters + replace_clusters > media_ptr -> fx_media_available_clusters)
465 #else
466
4/4
✓ Branch 13 → 14 taken 4 times.
✓ Branch 13 → 15 taken 118070 times.
✓ Branch 17 → 18 taken 6 times.
✓ Branch 17 → 20 taken 177350 times.
295430 if (clusters > media_ptr -> fx_media_available_clusters)
467 #endif /* FX_ENABLE_FAULT_TOLERANT */
468 {
469
470 #ifdef FX_ENABLE_FAULT_TOLERANT
471 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
472 #endif /* FX_ENABLE_FAULT_TOLERANT */
473
474 /* Release media protection. */
475 10 FX_UNPROTECT
476
477 /* Out of disk space. */
478 18 return(FX_NO_MORE_SPACE);
479 }
480
481 /* Update the file total cluster count. */
482 5544314 file_ptr -> fx_file_total_clusters = file_ptr -> fx_file_total_clusters + clusters;
483
484 /* Check for wrap-around when updating the available size. */
485
8/8
✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 17 taken 118068 times.
✓ Branch 20 → 21 taken 3 times.
✓ Branch 20 → 22 taken 177347 times.
✓ Branch 74 → 75 taken 2 times.
✓ Branch 74 → 76 taken 923961 times.
✓ Branch 83 → 84 taken 2 times.
✓ Branch 83 → 85 taken 4324929 times.
5544314 if (file_ptr -> fx_file_current_available_size + (ULONG64)bytes_per_cluster * (ULONG64)clusters > 0xFFFFFFFFULL)
486 {
487
488 /* 32-bit wrap around condition is present. Just set the available file size to all ones, which is
489 the maximum file size. */
490 9 file_ptr -> fx_file_current_available_size = 0xFFFFFFFFULL;
491 }
492 else
493 {
494
495 /* Normal condition, update the available size. */
496 5544305 file_ptr -> fx_file_current_available_size =
497 5544305 file_ptr -> fx_file_current_available_size + (ULONG64)bytes_per_cluster * (ULONG64)clusters;
498 }
499
500 #ifdef FX_ENABLE_FAULT_TOLERANT
501 /* Account for newly allocated clusters. */
502 5248894 clusters += replace_clusters;
503 #endif /* FX_ENABLE_FAULT_TOLERANT */
504
505 /* Decrease the available clusters in the media control block. */
506 5544314 media_ptr -> fx_media_available_clusters = media_ptr -> fx_media_available_clusters - clusters;
507
508
509 /* Search for the additional clusters we need. */
510 5544314 total_clusters = media_ptr -> fx_media_total_clusters;
511
512 #ifdef FX_ENABLE_FAULT_TOLERANT
513
4/4
✓ Branch 77 → 78 taken 656384 times.
✓ Branch 77 → 79 taken 267579 times.
✓ Branch 86 → 87 taken 656893 times.
✓ Branch 86 → 88 taken 3668038 times.
5248894 if (replace_clusters > 0)
514 {
515
516 /* Reset consecutive cluster. */
517 1313277 file_ptr -> fx_file_consecutive_cluster = 1;
518
519 1313277 last_cluster = insertion_front;
520
521 }
522 else
523 #endif /* FX_ENABLE_FAULT_TOLERANT */
524 {
525 4231037 last_cluster = file_ptr -> fx_file_last_physical_cluster;
526 }
527
528 5544314 FAT_index = media_ptr -> fx_media_cluster_search_start;
529
530 /* Loop to find the needed clusters. */
531
8/8
✓ Branch 44 → 19 taken 131022 times.
✓ Branch 44 → 45 taken 112205 times.
✓ Branch 52 → 24 taken 196778 times.
✓ Branch 52 → 53 taken 168586 times.
✓ Branch 117 → 81 taken 7110684 times.
✓ Branch 117 → 118 taken 918101 times.
✓ Branch 130 → 90 taken 36517741 times.
✓ Branch 130 → 131 taken 4319065 times.
49474182 while (clusters)
532 {
533
534 /* Decrease the cluster count. */
535 43956225 clusters--;
536
537 /* Loop to find the first available cluster. */
538 do
539 {
540
541 /* Make sure we stop looking after one pass through the FAT table. */
542
8/8
✓ Branch 20 → 21 taken 2 times.
✓ Branch 20 → 22 taken 136980 times.
✓ Branch 25 → 26 taken 3 times.
✓ Branch 25 → 28 taken 205715 times.
✓ Branch 82 → 83 taken 2 times.
✓ Branch 82 → 85 taken 7128660 times.
✓ Branch 91 → 92 taken 2 times.
✓ Branch 91 → 95 taken 36536360 times.
44007724 if (!total_clusters)
543 {
544
545 #ifdef FX_ENABLE_FAULT_TOLERANT
546 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
547 #endif /* FX_ENABLE_FAULT_TOLERANT */
548
549 /* Release media protection. */
550 5 FX_UNPROTECT
551
552 /* Something is wrong with the media - the desired clusters were
553 not found in the FAT table. */
554 9 return(FX_NO_MORE_SPACE);
555 }
556
557 /* Read FAT entry. */
558 44007715 status = _fx_utility_FAT_entry_read(media_ptr, FAT_index, &FAT_value);
559
560 /* Check for a bad status. */
561
8/8
✓ Branch 23 → 24 taken 5861 times.
✓ Branch 23 → 25 taken 131119 times.
✓ Branch 29 → 30 taken 8758 times.
✓ Branch 29 → 32 taken 196957 times.
✓ Branch 86 → 87 taken 5812 times.
✓ Branch 86 → 89 taken 7122844 times.
✓ Branch 96 → 97 taken 5812 times.
✓ Branch 96 → 100 taken 36530544 times.
44007707 if (status != FX_SUCCESS)
562 {
563
564 #ifdef FX_ENABLE_FAULT_TOLERANT
565 11624 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
566 #endif /* FX_ENABLE_FAULT_TOLERANT */
567
568 /* Release media protection. */
569 14570 FX_UNPROTECT
570
571 /* Return the bad status. */
572 26243 return(status);
573 }
574
575 /* Decrement the total cluster count. */
576 43981464 total_clusters--;
577
578 /* Determine if the FAT entry is free. */
579
8/8
✓ Branch 25 → 26 taken 125159 times.
✓ Branch 25 → 29 taken 5960 times.
✓ Branch 32 → 33 taken 188017 times.
✓ Branch 32 → 36 taken 8940 times.
✓ Branch 89 → 90 taken 7104866 times.
✓ Branch 89 → 93 taken 17978 times.
✓ Branch 100 → 101 taken 36511923 times.
✓ Branch 100 → 104 taken 18621 times.
43981464 if (FAT_value == FX_FREE_CLUSTER)
580 {
581
582 /* Move cluster search pointer forward. */
583 43929965 media_ptr -> fx_media_cluster_search_start = FAT_index + 1;
584
585 /* Determine if this needs to be wrapped. */
586
8/8
✓ Branch 26 → 27 taken 32 times.
✓ Branch 26 → 28 taken 125127 times.
✓ Branch 33 → 34 taken 49 times.
✓ Branch 33 → 35 taken 187968 times.
✓ Branch 90 → 91 taken 9987 times.
✓ Branch 90 → 92 taken 7094879 times.
✓ Branch 101 → 102 taken 10208 times.
✓ Branch 101 → 103 taken 36501715 times.
43929965 if (media_ptr -> fx_media_cluster_search_start >= (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START))
587 {
588
589 /* Wrap the search to the beginning FAT entry. */
590 20276 media_ptr -> fx_media_cluster_search_start = FX_FAT_ENTRY_START;
591 }
592
593 /* Break this loop. */
594 43929965 break;
595 }
596 else
597 {
598
599 /* FAT entry is not free... Advance the FAT index. */
600 51499 FAT_index++;
601
602 /* Determine if we need to wrap the FAT index around. */
603
8/8
✓ Branch 29 → 30 taken 2 times.
✓ Branch 29 → 31 taken 5958 times.
✓ Branch 36 → 37 taken 3 times.
✓ Branch 36 → 38 taken 8937 times.
✓ Branch 93 → 94 taken 9 times.
✓ Branch 93 → 95 taken 17969 times.
✓ Branch 104 → 105 taken 11 times.
✓ Branch 104 → 106 taken 18610 times.
51499 if (FAT_index >= (media_ptr -> fx_media_total_clusters + FX_FAT_ENTRY_START))
604 {
605
606 /* Wrap the search to the beginning FAT entry. */
607 25 FAT_index = FX_FAT_ENTRY_START;
608 }
609 }
610 } while (FX_TRUE);
611
612 /* Determine if we have found the first new cluster yet. */
613
8/8
✓ Branch 32 → 33 taken 112207 times.
✓ Branch 32 → 34 taken 12952 times.
✓ Branch 39 → 40 taken 168589 times.
✓ Branch 39 → 41 taken 19428 times.
✓ Branch 96 → 97 taken 918149 times.
✓ Branch 96 → 104 taken 6186717 times.
✓ Branch 107 → 108 taken 4319117 times.
✓ Branch 107 → 116 taken 32192806 times.
43929965 if (first_new_cluster == 0)
614 {
615
616 /* Remember the first new cluster. */
617 5518062 first_new_cluster = FAT_index;
618
619 #ifdef FX_ENABLE_FAULT_TOLERANT
620
4/4
✓ Branch 97 → 98 taken 805912 times.
✓ Branch 97 → 104 taken 112237 times.
✓ Branch 108 → 109 taken 4206880 times.
✓ Branch 108 → 116 taken 112237 times.
5237266 if (media_ptr -> fx_media_fault_tolerant_enabled)
621 {
622
623 /* Set the undo log now. */
624
4/4
✓ Branch 98 → 99 taken 149526 times.
✓ Branch 98 → 100 taken 656386 times.
✓ Branch 109 → 110 taken 3549985 times.
✓ Branch 109 → 111 taken 656895 times.
5012792 if (copy_head_cluster == 0)
625 {
626 3699511 status = _fx_fault_tolerant_set_FAT_chain(media_ptr, FX_FALSE, file_ptr -> fx_file_current_physical_cluster,
627 first_new_cluster, media_ptr -> fx_media_fat_last, media_ptr -> fx_media_fat_last);
628 }
629 else
630 {
631
632 1313281 status = _fx_fault_tolerant_set_FAT_chain(media_ptr, FX_FALSE, insertion_front, first_new_cluster,
633 copy_head_cluster, insertion_back);
634 }
635
636 /* Check for good completion status. */
637
4/4
✓ Branch 101 → 102 taken 4 times.
✓ Branch 101 → 104 taken 805872 times.
✓ Branch 112 → 113 taken 4 times.
✓ Branch 112 → 116 taken 4206836 times.
5012716 if (status != FX_SUCCESS)
638 {
639
640 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
641
642 /* Release media protection. */
643 4 FX_UNPROTECT
644
645 /* Return the error status. */
646 8 return(status);
647 }
648 }
649 #endif /* FX_ENABLE_FAULT_TOLERANT */
650 }
651
652 /* Make a quick check to see if an empty, cluster-less file
653 is being written to for the first time. */
654
8/8
✓ Branch 34 → 35 taken 112807 times.
✓ Branch 34 → 42 taken 12352 times.
✓ Branch 41 → 42 taken 169487 times.
✓ Branch 41 → 50 taken 18530 times.
✓ Branch 104 → 105 taken 6929388 times.
✓ Branch 104 → 113 taken 175438 times.
✓ Branch 116 → 117 taken 32935463 times.
✓ Branch 116 → 126 taken 3576416 times.
43929881 if (last_cluster)
655 {
656
657 /* Check for the file's cluster. We won't perform this link until the
658 entire FAT chain is built. */
659
8/8
✓ Branch 35 → 36 taken 12952 times.
✓ Branch 35 → 37 taken 99855 times.
✓ Branch 42 → 43 taken 19428 times.
✓ Branch 42 → 44 taken 150059 times.
✓ Branch 105 → 106 taken 6681182 times.
✓ Branch 105 → 107 taken 248206 times.
✓ Branch 117 → 118 taken 32687257 times.
✓ Branch 117 → 119 taken 248206 times.
40147145 if (last_cluster != file_ptr -> fx_file_last_physical_cluster)
660 {
661
662 /* Normal condition - link the last cluster with the new
663 found cluster. */
664 39400819 status = _fx_utility_FAT_entry_write(media_ptr, last_cluster, FAT_index);
665 }
666
667 /* Check for a bad FAT write status. */
668
8/8
✓ Branch 37 → 38 taken 2 times.
✓ Branch 37 → 39 taken 112805 times.
✓ Branch 44 → 45 taken 3 times.
✓ Branch 44 → 47 taken 169484 times.
✓ Branch 107 → 108 taken 2 times.
✓ Branch 107 → 110 taken 6929384 times.
✓ Branch 119 → 120 taken 2 times.
✓ Branch 119 → 123 taken 32935459 times.
40147141 if (status != FX_SUCCESS)
669 {
670
671 #ifdef FX_ENABLE_FAULT_TOLERANT
672 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
673 #endif /* FX_ENABLE_FAULT_TOLERANT */
674
675 /* Release media protection. */
676 5 FX_UNPROTECT
677
678 /* Return the bad status. */
679 9 return(status);
680 }
681
682 /* Determine if we are adding a sector after a write filled the previously
683 allocated cluster exactly. */
684 40147132 if ((file_ptr -> fx_file_current_relative_sector >=
685
8/8
✓ Branch 39 → 40 taken 112619 times.
✓ Branch 39 → 43 taken 186 times.
✓ Branch 47 → 48 taken 169205 times.
✓ Branch 47 → 51 taken 279 times.
✓ Branch 110 → 111 taken 730026 times.
✓ Branch 110 → 116 taken 6199358 times.
✓ Branch 123 → 124 taken 26735365 times.
✓ Branch 123 → 129 taken 6200094 times.
40147132 (media_ptr -> fx_media_sectors_per_cluster - 1)) &&
686 27747215 (file_ptr -> fx_file_current_logical_offset >=
687
8/8
✓ Branch 40 → 41 taken 72775 times.
✓ Branch 40 → 43 taken 39844 times.
✓ Branch 48 → 49 taken 109640 times.
✓ Branch 48 → 51 taken 59565 times.
✓ Branch 111 → 112 taken 221116 times.
✓ Branch 111 → 116 taken 508910 times.
✓ Branch 124 → 125 taken 221116 times.
✓ Branch 124 → 129 taken 26514249 times.
27747215 media_ptr -> fx_media_bytes_per_sector))
688 {
689
690 /* Yes, we need to adjust all of the pertinent file parameters for
691 writing into this newly allocated cluster. */
692 624647 file_ptr -> fx_file_current_physical_cluster = FAT_index;
693 624647 file_ptr -> fx_file_current_relative_cluster++;
694 624647 file_ptr -> fx_file_current_relative_sector = 0;
695 624647 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
696 624647 (((ULONG64)(FAT_index - FX_FAT_ENTRY_START)) *
697 624647 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
698 624647 file_ptr -> fx_file_current_logical_offset = 0;
699 }
700 }
701 else
702 {
703
704 /* This is the first cluster allocated for the file. Just
705 remember it as being the first and setup the other file
706 pointers accordingly. */
707 3782736 file_ptr -> fx_file_first_physical_cluster = FAT_index;
708 3782736 file_ptr -> fx_file_current_physical_cluster = FAT_index;
709 3782736 file_ptr -> fx_file_current_relative_cluster = 0;
710 3782736 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
711 3782736 (((ULONG64)(FAT_index - FX_FAT_ENTRY_START)) *
712 3782736 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
713 #ifdef FX_ENABLE_FAULT_TOLERANT
714
4/4
✓ Branch 113 → 114 taken 13547 times.
✓ Branch 113 → 115 taken 161891 times.
✓ Branch 126 → 127 taken 3414002 times.
✓ Branch 126 → 128 taken 162414 times.
3751854 if (file_ptr -> fx_file_last_physical_cluster == 0)
715 #endif /* FX_ENABLE_FAULT_TOLERANT */
716 {
717 3458431 file_ptr -> fx_file_current_logical_offset = 0;
718 3458431 file_ptr -> fx_file_current_file_offset = 0;
719 }
720
721 /* Also remember this as the first cluster in the directory
722 entry. */
723 3782736 file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster = FAT_index;
724 }
725
726 /* Otherwise, remember the new FAT index as the last. */
727 43929868 last_cluster = FAT_index;
728
729 /* Move to the next FAT entry. */
730 43929868 FAT_index = media_ptr -> fx_media_cluster_search_start;
731 }
732
733 #ifdef FX_ENABLE_FAULT_TOLERANT
734
4/4
✓ Branch 118 → 119 taken 805866 times.
✓ Branch 118 → 120 taken 112235 times.
✓ Branch 131 → 132 taken 4206830 times.
✓ Branch 131 → 133 taken 112235 times.
5237166 if (media_ptr -> fx_media_fault_tolerant_enabled)
735 {
736
737 /* Link the last cluster back to original FAT. */
738 5012696 status = _fx_utility_FAT_entry_write(media_ptr, last_cluster, insertion_back);
739 }
740 else
741 #endif /* FX_ENABLE_FAULT_TOLERANT */
742 {
743
744 /* Place an end-of-file marker on the last cluster. */
745 505261 status = _fx_utility_FAT_entry_write(media_ptr, last_cluster, media_ptr -> fx_media_fat_last);
746 }
747
748 /* Check for a bad FAT write status. */
749
8/8
✓ Branch 46 → 47 taken 2 times.
✓ Branch 46 → 48 taken 112203 times.
✓ Branch 54 → 55 taken 3 times.
✓ Branch 54 → 57 taken 168583 times.
✓ Branch 121 → 122 taken 2 times.
✓ Branch 121 → 124 taken 918099 times.
✓ Branch 134 → 135 taken 2 times.
✓ Branch 134 → 138 taken 4319063 times.
5517957 if (status != FX_SUCCESS)
750 {
751 #ifdef FX_ENABLE_FAULT_TOLERANT
752 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
753 #endif /* FX_ENABLE_FAULT_TOLERANT */
754
755 /* Release media protection. */
756 5 FX_UNPROTECT
757
758 /* Return the bad status. */
759 9 return(status);
760 }
761
762
763 /* Determine if the file already had clusters. */
764
8/8
✓ Branch 48 → 49 taken 99855 times.
✓ Branch 48 → 52 taken 12348 times.
✓ Branch 57 → 58 taken 150059 times.
✓ Branch 57 → 62 taken 18524 times.
✓ Branch 124 → 125 taken 904562 times.
✓ Branch 124 → 134 taken 13537 times.
✓ Branch 138 → 139 taken 905071 times.
✓ Branch 138 → 149 taken 3413992 times.
5517948 if (file_ptr -> fx_file_last_physical_cluster)
765 {
766
767 /* Now, link the file's old last cluster to the first cluster of the new chain. */
768 #ifdef FX_ENABLE_FAULT_TOLERANT
769
4/4
✓ Branch 125 → 126 taken 494465 times.
✓ Branch 125 → 127 taken 410097 times.
✓ Branch 139 → 140 taken 494451 times.
✓ Branch 139 → 141 taken 410620 times.
1809633 if (insertion_front)
770 {
771 988916 status = _fx_utility_FAT_entry_write(media_ptr, insertion_front, first_new_cluster);
772 }
773
8/8
✓ Branch 127 → 128 taken 310199 times.
✓ Branch 127 → 130 taken 99898 times.
✓ Branch 128 → 129 taken 148308 times.
✓ Branch 128 → 131 taken 161891 times.
✓ Branch 141 → 142 taken 310722 times.
✓ Branch 141 → 144 taken 99898 times.
✓ Branch 142 → 143 taken 148308 times.
✓ Branch 142 → 145 taken 162414 times.
820717 else if ((media_ptr -> fx_media_fault_tolerant_enabled == FX_FALSE) ||
774
4/4
✓ Branch 129 → 130 taken 148306 times.
✓ Branch 129 → 131 taken 2 times.
✓ Branch 143 → 144 taken 148306 times.
✓ Branch 143 → 145 taken 2 times.
296616 ((replace_clusters == 0) && (first_new_cluster)))
775 {
776 496408 status = _fx_utility_FAT_entry_write(media_ptr, file_ptr -> fx_file_last_physical_cluster, first_new_cluster);
777 }
778 #else
779 249914 status = _fx_utility_FAT_entry_write(media_ptr, file_ptr -> fx_file_last_physical_cluster, first_new_cluster);
780 #endif /* FX_ENABLE_FAULT_TOLERANT */
781
782 /* Check for a bad FAT write status. */
783
8/8
✓ Branch 50 → 51 taken 2 times.
✓ Branch 50 → 52 taken 99853 times.
✓ Branch 59 → 60 taken 3 times.
✓ Branch 59 → 62 taken 150056 times.
✓ Branch 131 → 132 taken 2 times.
✓ Branch 131 → 134 taken 904558 times.
✓ Branch 145 → 146 taken 2 times.
✓ Branch 145 → 149 taken 905067 times.
2059543 if (status != FX_SUCCESS)
784 {
785 #ifdef FX_ENABLE_FAULT_TOLERANT
786 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
787 #endif /* FX_ENABLE_FAULT_TOLERANT */
788
789 /* Release media protection. */
790 5 FX_UNPROTECT
791
792 /* Return the bad status. */
793 9 return(status);
794 }
795 }
796
797 #ifdef FX_FAULT_TOLERANT
798
799
800 /* Ensure the new FAT chain is properly written to the media. */
801
802 /* Flush the cached individual FAT entries */
803 5237154 _fx_utility_FAT_flush(media_ptr);
804 #endif
805
806 #ifdef FX_ENABLE_FAULT_TOLERANT
807
4/4
✓ Branch 135 → 136 taken 805834 times.
✓ Branch 135 → 138 taken 112231 times.
✓ Branch 150 → 151 taken 4206794 times.
✓ Branch 150 → 153 taken 112231 times.
5237090 if (media_ptr -> fx_media_fault_tolerant_enabled)
808 {
809
810 /* Clear undo phase. */
811 5012628 media_ptr -> fx_media_fault_tolerant_state &= (UCHAR)(~FX_FAULT_TOLERANT_STATE_SET_FAT_CHAIN & 0xff);
812
813 /* Update the last cluster? */
814
4/4
✓ Branch 136 → 137 taken 427248 times.
✓ Branch 136 → 139 taken 378586 times.
✓ Branch 151 → 152 taken 3826956 times.
✓ Branch 151 → 154 taken 379838 times.
5012628 if (insertion_back == media_ptr -> fx_media_fat_last)
815 {
816
817 /* Yes. Update the file control block with the last physical cluster. */
818 4254204 file_ptr -> fx_file_last_physical_cluster = last_cluster;
819 }
820 }
821 else
822 #endif /* FX_ENABLE_FAULT_TOLERANT */
823 {
824
825 /* Update the file control block with the last physical cluster. */
826 505243 file_ptr -> fx_file_last_physical_cluster = last_cluster;
827 }
828 }
829
830 /* Check for a need to increment to the next sector within a previously
831 allocated cluster. */
832 162217601 if (file_ptr -> fx_file_current_logical_offset >=
833
8/8
✓ Branch 53 → 54 taken 12899 times.
✓ Branch 53 → 55 taken 1205807 times.
✓ Branch 63 → 64 taken 17574 times.
✓ Branch 63 → 65 taken 1797990 times.
✓ Branch 139 → 140 taken 13240 times.
✓ Branch 139 → 141 taken 77878200 times.
✓ Branch 154 → 155 taken 13240 times.
✓ Branch 154 → 156 taken 81278651 times.
162217601 media_ptr -> fx_media_bytes_per_sector)
834 {
835
836 /* Update the sector specific file parameters to start at the
837 next logical sector. */
838 56953 file_ptr -> fx_file_current_logical_sector++;
839 56953 file_ptr -> fx_file_current_relative_sector++;
840 56953 file_ptr -> fx_file_current_logical_offset = 0;
841 }
842
843 /* At this point there is enough room to perform the file write operation. */
844
845 /* Setup local buffer pointer. */
846 162217601 source_ptr = (UCHAR *)buffer_ptr;
847
848 /* Setup the remaining number of bytes to write. */
849 162217601 bytes_remaining = size;
850
851 #ifdef FX_ENABLE_FAULT_TOLERANT
852
4/4
✓ Branch 141 → 142 taken 656332 times.
✓ Branch 141 → 153 taken 77235108 times.
✓ Branch 156 → 157 taken 656841 times.
✓ Branch 156 → 170 taken 80635050 times.
159183331 if (replace_clusters > 0)
853 {
854
855 /* Force update current cluster and sector. */
856 1313173 file_ptr -> fx_file_current_physical_cluster = first_new_cluster;
857 1313173 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
858 1313173 (((ULONG64)(first_new_cluster - FX_FAT_ENTRY_START)) *
859 1313173 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) +
860 1313173 file_ptr -> fx_file_current_relative_sector;
861
862 /* Copy sectors in replaced cluster but not overwritten at the front. */
863
4/4
✓ Branch 152 → 143 taken 1767347 times.
✓ Branch 152 → 153 taken 656292 times.
✓ Branch 169 → 158 taken 1765962 times.
✓ Branch 169 → 170 taken 656801 times.
4846402 for (i = 0; i < file_ptr -> fx_file_current_relative_sector; i++)
864 {
865 3533309 status = _fx_utility_logical_sector_read(media_ptr,
866 3533309 ((ULONG)media_ptr -> fx_media_data_sector_start) +
867 3533309 (((ULONG)(copy_head_cluster - FX_FAT_ENTRY_START)) *
868 3533309 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + i,
869 3533309 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
870
871 /* Check for good completion status. */
872
4/4
✓ Branch 144 → 145 taken 2 times.
✓ Branch 144 → 147 taken 1767345 times.
✓ Branch 159 → 160 taken 2 times.
✓ Branch 159 → 163 taken 1765960 times.
3533309 if (status != FX_SUCCESS)
873 {
874
875 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
876
877 /* Release media protection. */
878 2 FX_UNPROTECT
879
880 /* Return the error status. */
881 4 return(status);
882 }
883
884 /* Write back the current logical sector. */
885 3533305 status = _fx_utility_logical_sector_write(media_ptr,
886 3533305 ((ULONG)media_ptr -> fx_media_data_sector_start) +
887 3533305 (((ULONG)(file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START)) *
888 3533305 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + i,
889 3533305 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
890
891 /* Check for good completion status. */
892
4/4
✓ Branch 148 → 149 taken 2 times.
✓ Branch 148 → 151 taken 1767307 times.
✓ Branch 164 → 165 taken 2 times.
✓ Branch 164 → 168 taken 1765922 times.
3533233 if (status != FX_SUCCESS)
893 {
894
895 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
896
897 /* Release media protection. */
898 2 FX_UNPROTECT
899
900 /* Return the error status. */
901 4 return(status);
902 }
903 }
904 }
905 #endif /* FX_ENABLE_FAULT_TOLERANT */
906
907 /* Loop to write all of the bytes. */
908
8/8
✓ Branch 102 → 56 taken 1257571 times.
✓ Branch 102 → 103 taken 1065274 times.
✓ Branch 117 → 66 taken 1873554 times.
✓ Branch 117 → 118 taken 1602255 times.
✓ Branch 211 → 154 taken 79082190 times.
✓ Branch 211 → 212 taken 77589654 times.
✓ Branch 233 → 171 taken 83683977 times.
✓ Branch 233 → 234 taken 79189866 times.
325344341 while (bytes_remaining)
909 {
910
911 /* Determine if a beginning or ending partial write is required. */
912
8/8
✓ Branch 56 → 57 taken 193573 times.
✓ Branch 56 → 58 taken 1063998 times.
✓ Branch 66 → 67 taken 281900 times.
✓ Branch 66 → 68 taken 1591654 times.
✓ Branch 154 → 155 taken 2538275 times.
✓ Branch 154 → 156 taken 76543915 times.
✓ Branch 171 → 172 taken 7140154 times.
✓ Branch 171 → 173 taken 76543823 times.
165897292 if ((file_ptr -> fx_file_current_logical_offset) ||
913
8/8
✓ Branch 57 → 58 taken 125611 times.
✓ Branch 57 → 68 taken 67962 times.
✓ Branch 67 → 68 taken 180245 times.
✓ Branch 67 → 80 taken 101655 times.
✓ Branch 155 → 156 taken 1968236 times.
✓ Branch 155 → 174 taken 570039 times.
✓ Branch 172 → 173 taken 3569028 times.
✓ Branch 172 → 193 taken 3571126 times.
10153902 (bytes_remaining < media_ptr -> fx_media_bytes_per_sector))
914 {
915
916 /* A partial sector write is required. */
917
918 /* Read the current logical sector. */
919 #ifdef FX_ENABLE_FAULT_TOLERANT
920
4/4
✓ Branch 156 → 157 taken 1310525 times.
✓ Branch 156 → 162 taken 77201626 times.
✓ Branch 173 → 174 taken 1311553 times.
✓ Branch 173 → 179 taken 78801298 times.
158625002 if (replace_clusters > 0)
921 {
922
4/4
✓ Branch 157 → 158 taken 907064 times.
✓ Branch 157 → 159 taken 403461 times.
✓ Branch 174 → 175 taken 906558 times.
✓ Branch 174 → 176 taken 404995 times.
2622078 if (file_ptr -> fx_file_current_physical_cluster == first_new_cluster)
923 {
924
925 /* It's at beginning. */
926 1813622 status = _fx_utility_logical_sector_read(media_ptr,
927 1813622 ((ULONG)media_ptr -> fx_media_data_sector_start) +
928 1813622 (((ULONG)(copy_head_cluster - FX_FAT_ENTRY_START)) *
929 1813622 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) +
930 1813622 file_ptr -> fx_file_current_relative_sector,
931 1813622 media_ptr -> fx_media_memory_buffer, (ULONG)1, FX_DATA_SECTOR);
932 }
933
4/4
✓ Branch 159 → 160 taken 403357 times.
✓ Branch 159 → 161 taken 104 times.
✓ Branch 176 → 177 taken 404891 times.
✓ Branch 176 → 178 taken 104 times.
808456 else if (data_append == FX_FALSE)
934 {
935
936 /* It's at ending. */
937 808248 status = _fx_utility_logical_sector_read(media_ptr,
938 808248 ((ULONG)media_ptr -> fx_media_data_sector_start) +
939 808248 (((ULONG)(copy_tail_cluster - FX_FAT_ENTRY_START)) *
940 808248 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) +
941 808248 file_ptr -> fx_file_current_relative_sector,
942 808248 media_ptr -> fx_media_memory_buffer, (ULONG)1, FX_DATA_SECTOR);
943 }
944 else
945 {
946
947 /* It's at ending. */
948 208 status = _fx_utility_logical_sector_read(media_ptr,
949 file_ptr -> fx_file_current_logical_sector,
950 208 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
951 }
952 }
953 else
954 #endif /* FX_ENABLE_FAULT_TOLERANT */
955 {
956 158964432 status = _fx_utility_logical_sector_read(media_ptr,
957 file_ptr -> fx_file_current_logical_sector,
958 158964432 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
959 }
960
961 /* Check for good completion status. */
962
8/8
✓ Branch 59 → 60 taken 45343 times.
✓ Branch 59 → 61 taken 1144266 times.
✓ Branch 69 → 70 taken 58708 times.
✓ Branch 69 → 72 taken 1713191 times.
✓ Branch 163 → 164 taken 35924 times.
✓ Branch 163 → 166 taken 78476227 times.
✓ Branch 180 → 181 taken 35924 times.
✓ Branch 180 → 184 taken 80076927 times.
161586510 if (status != FX_SUCCESS)
963 {
964 #ifdef FX_ENABLE_FAULT_TOLERANT
965 71848 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
966 #endif /* FX_ENABLE_FAULT_TOLERANT */
967
968 /* Release media protection. */
969 94632 FX_UNPROTECT
970
971 /* Return the error status. */
972 175899 return(status);
973 }
974
975 /* Copy the appropriate number of bytes into the destination buffer. */
976 161410611 copy_bytes = media_ptr -> fx_media_bytes_per_sector -
977 161410611 file_ptr -> fx_file_current_logical_offset;
978
979 /* Check to see if only a portion of the sector needs to be
980 copied. */
981
8/8
✓ Branch 61 → 62 taken 1052337 times.
✓ Branch 61 → 63 taken 91929 times.
✓ Branch 72 → 73 taken 1577170 times.
✓ Branch 72 → 74 taken 136021 times.
✓ Branch 166 → 167 taken 76539916 times.
✓ Branch 166 → 168 taken 1936311 times.
✓ Branch 184 → 185 taken 78140122 times.
✓ Branch 184 → 186 taken 1936805 times.
161410611 if (copy_bytes > bytes_remaining)
982 {
983
984 /* Adjust the number of bytes to copy. */
985 157309545 copy_bytes = (ULONG)bytes_remaining;
986 }
987
988 /* Actually perform the memory copy. */
989 161410611 _fx_utility_memory_copy(source_ptr, ((UCHAR *)media_ptr -> fx_media_memory_buffer) + /* Use case of memcpy is verified. */
990 161410611 file_ptr -> fx_file_current_logical_offset,
991 copy_bytes);
992
993 /* Write back the current logical sector. */
994 161410611 status = _fx_utility_logical_sector_write(media_ptr, file_ptr -> fx_file_current_logical_sector,
995 161410611 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
996
997 /* Check for good completion status. */
998
8/8
✓ Branch 65 → 66 taken 20507 times.
✓ Branch 65 → 67 taken 1123759 times.
✓ Branch 76 → 77 taken 24660 times.
✓ Branch 76 → 79 taken 1688531 times.
✓ Branch 170 → 171 taken 28702 times.
✓ Branch 170 → 173 taken 78447514 times.
✓ Branch 188 → 189 taken 28702 times.
✓ Branch 188 → 192 taken 80048212 times.
161410587 if (status != FX_SUCCESS)
999 {
1000 #ifdef FX_ENABLE_FAULT_TOLERANT
1001 57404 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1002 #endif /* FX_ENABLE_FAULT_TOLERANT */
1003
1004 /* Release media protection. */
1005 53362 FX_UNPROTECT
1006
1007 /* Return the error status. */
1008 102571 return(status);
1009 }
1010
1011
1012 /* Increment the logical sector byte offset. */
1013 161308016 file_ptr -> fx_file_current_logical_offset =
1014 161308016 file_ptr -> fx_file_current_logical_offset + copy_bytes;
1015
1016 /* Adjust the remaining bytes to read. */
1017 161308016 bytes_remaining = bytes_remaining - copy_bytes;
1018
1019 /* Adjust the pointer to the source buffer. */
1020 161308016 source_ptr = source_ptr + copy_bytes;
1021 }
1022 else
1023 {
1024
1025 /* Attempt to write multiple sectors directly to the media. */
1026
1027 /* Calculate the number of whole sectors to write. */
1028 4310782 sectors = (UINT)(bytes_remaining / media_ptr -> fx_media_bytes_per_sector);
1029
1030 4310782 next_cluster = cluster = file_ptr -> fx_file_current_physical_cluster;
1031
1032 4310782 for (i = (media_ptr -> fx_media_sectors_per_cluster -
1033
8/8
✓ Branch 79 → 69 taken 1503 times.
✓ Branch 79 → 80 taken 67481 times.
✓ Branch 92 → 81 taken 2351 times.
✓ Branch 92 → 93 taken 100837 times.
✓ Branch 186 → 175 taken 5887303 times.
✓ Branch 186 → 187 taken 566563 times.
✓ Branch 206 → 194 taken 30692451 times.
✓ Branch 206 → 207 taken 3567403 times.
40885892 file_ptr -> fx_file_current_relative_sector); i < sectors; i += media_ptr -> fx_media_sectors_per_cluster)
1034 {
1035 36583608 status = _fx_utility_FAT_entry_read(media_ptr, cluster, &next_cluster);
1036
1037 /* Determine if an error is present. */
1038
16/16
✓ Branch 70 → 71 taken 1251 times.
✓ Branch 70 → 73 taken 252 times.
✓ Branch 71 → 72 taken 1249 times.
✓ Branch 71 → 73 taken 2 times.
✓ Branch 82 → 83 taken 1925 times.
✓ Branch 82 → 85 taken 426 times.
✓ Branch 83 → 84 taken 1922 times.
✓ Branch 83 → 85 taken 3 times.
✓ Branch 176 → 177 taken 5887128 times.
✓ Branch 176 → 179 taken 175 times.
✓ Branch 177 → 178 taken 5887126 times.
✓ Branch 177 → 179 taken 2 times.
✓ Branch 195 → 196 taken 30692276 times.
✓ Branch 195 → 198 taken 175 times.
✓ Branch 196 → 197 taken 30692274 times.
✓ Branch 196 → 198 taken 2 times.
36583608 if ((status != FX_SUCCESS) || (next_cluster < FX_FAT_ENTRY_START) ||
1039
8/8
✓ Branch 72 → 73 taken 223 times.
✓ Branch 72 → 76 taken 1026 times.
✓ Branch 84 → 85 taken 383 times.
✓ Branch 84 → 89 taken 1539 times.
✓ Branch 178 → 179 taken 159 times.
✓ Branch 178 → 183 taken 5886967 times.
✓ Branch 197 → 198 taken 159 times.
✓ Branch 197 → 203 taken 30692115 times.
36582571 (next_cluster > media_ptr -> fx_media_fat_reserved))
1040 {
1041 #ifdef FX_ENABLE_FAULT_TOLERANT
1042 672 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1043 #endif /* FX_ENABLE_FAULT_TOLERANT */
1044
1045 /* Release media protection. */
1046 1148 FX_UNPROTECT
1047
1048 /* Send error message back to caller. */
1049
8/8
✓ Branch 73 → 74 taken 252 times.
✓ Branch 73 → 75 taken 225 times.
✓ Branch 86 → 87 taken 426 times.
✓ Branch 86 → 88 taken 386 times.
✓ Branch 180 → 181 taken 175 times.
✓ Branch 180 → 182 taken 161 times.
✓ Branch 200 → 201 taken 175 times.
✓ Branch 200 → 202 taken 161 times.
1961 if (status != FX_SUCCESS)
1050 {
1051 1028 return(status);
1052 }
1053 else
1054 {
1055 933 return(FX_FILE_CORRUPT);
1056 }
1057 }
1058
1059
8/8
✓ Branch 76 → 77 taken 4 times.
✓ Branch 76 → 78 taken 1022 times.
✓ Branch 89 → 90 taken 6 times.
✓ Branch 89 → 91 taken 1533 times.
✓ Branch 183 → 184 taken 3140 times.
✓ Branch 183 → 185 taken 5883827 times.
✓ Branch 203 → 204 taken 3387 times.
✓ Branch 203 → 205 taken 30688728 times.
36581647 if (next_cluster != cluster + 1)
1060 {
1061 6537 break;
1062 }
1063 else
1064 {
1065 36575110 cluster = next_cluster;
1066 }
1067 }
1068
1069
8/8
✓ Branch 80 → 81 taken 4 times.
✓ Branch 80 → 82 taken 67481 times.
✓ Branch 93 → 94 taken 6 times.
✓ Branch 93 → 95 taken 100837 times.
✓ Branch 187 → 188 taken 3140 times.
✓ Branch 187 → 189 taken 566563 times.
✓ Branch 207 → 208 taken 3387 times.
✓ Branch 207 → 209 taken 3567403 times.
4308821 if (i < sectors)
1070 {
1071 6537 sectors = i;
1072 }
1073
1074 /* Perform the data write directly from the user's buffer of
1075 the appropriate number of sectors. */
1076 4308821 status = _fx_utility_logical_sector_write(media_ptr, file_ptr -> fx_file_current_logical_sector,
1077 source_ptr, (ULONG) sectors, FX_DATA_SECTOR);
1078
1079 /* Check for good completion status. */
1080
8/8
✓ Branch 83 → 84 taken 1335 times.
✓ Branch 83 → 85 taken 66150 times.
✓ Branch 96 → 97 taken 1770 times.
✓ Branch 96 → 99 taken 99073 times.
✓ Branch 190 → 191 taken 2104 times.
✓ Branch 190 → 193 taken 567564 times.
✓ Branch 210 → 211 taken 2104 times.
✓ Branch 210 → 214 taken 3568649 times.
4308749 if (status != FX_SUCCESS)
1081 {
1082 #ifdef FX_ENABLE_FAULT_TOLERANT
1083 4208 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1084 #endif /* FX_ENABLE_FAULT_TOLERANT */
1085
1086 /* Release media protection. */
1087 3874 FX_UNPROTECT
1088
1089 /* Return the error status. */
1090 7313 return(status);
1091 }
1092
1093 /* Now adjust the various file pointers. */
1094
1095 /* Increment the current logical sector. Subtract one from
1096 the sector count because we are going to use the logical
1097 offset to do additional sector/cluster arithmetic below. */
1098 4301436 file_ptr -> fx_file_current_logical_sector =
1099 4301436 file_ptr -> fx_file_current_logical_sector +
1100 4301436 (sectors - 1);
1101
1102 /* Move the relative cluster and sector as well. */
1103 4301436 file_ptr -> fx_file_current_relative_cluster = file_ptr -> fx_file_current_relative_cluster +
1104 4301436 (file_ptr -> fx_file_current_relative_sector + (sectors - 1)) /
1105 4301436 media_ptr -> fx_media_sectors_per_cluster;
1106
1107 4301436 file_ptr -> fx_file_current_relative_sector =
1108 4301436 (file_ptr -> fx_file_current_relative_sector + (sectors - 1)) %
1109 4301436 media_ptr -> fx_media_sectors_per_cluster;
1110
1111 /* Increment the logical sector byte offset. */
1112 4301436 file_ptr -> fx_file_current_logical_offset =
1113 4301436 media_ptr -> fx_media_bytes_per_sector;
1114
1115 4301436 file_ptr -> fx_file_current_physical_cluster = cluster;
1116
1117 /* Adjust the remaining bytes. */
1118 4301436 bytes_remaining = bytes_remaining -
1119 4301436 (((ULONG)media_ptr -> fx_media_bytes_per_sector) * sectors);
1120
1121 /* Adjust the pointer to the source buffer. */
1122 4301436 source_ptr = source_ptr +
1123 4301436 (((ULONG)media_ptr -> fx_media_bytes_per_sector) * sectors);
1124 }
1125
1126 /* At this point, we have either written a partial sector or have successfully
1127 written one or more whole sectors. Determine if we are at the end of
1128 the current logical sector. */
1129 165609452 if (file_ptr -> fx_file_current_logical_offset >=
1130
8/8
✓ Branch 86 → 87 taken 155043 times.
✓ Branch 86 → 101 taken 1034866 times.
✓ Branch 100 → 101 taken 231065 times.
✓ Branch 100 → 116 taken 1556539 times.
✓ Branch 194 → 195 taken 2496811 times.
✓ Branch 194 → 210 taken 76518267 times.
✓ Branch 215 → 216 taken 5498390 times.
✓ Branch 215 → 232 taken 78118471 times.
165609452 media_ptr -> fx_media_bytes_per_sector)
1131 {
1132
1133 /* Determine if we are at the exact physical end of the file. */
1134
8/8
✓ Branch 87 → 88 taken 110526 times.
✓ Branch 87 → 90 taken 44517 times.
✓ Branch 101 → 102 taken 166226 times.
✓ Branch 101 → 104 taken 64839 times.
✓ Branch 195 → 196 taken 1300407 times.
✓ Branch 195 → 198 taken 1196404 times.
✓ Branch 216 → 217 taken 3100617 times.
✓ Branch 216 → 219 taken 2397773 times.
8381309 if ((bytes_remaining == 0) &&
1135 4677776 ((file_ptr -> fx_file_current_file_offset + size) >=
1136
8/8
✓ Branch 88 → 89 taken 73324 times.
✓ Branch 88 → 90 taken 37202 times.
✓ Branch 102 → 103 taken 110553 times.
✓ Branch 102 → 104 taken 55673 times.
✓ Branch 196 → 197 taken 221323 times.
✓ Branch 196 → 198 taken 1079084 times.
✓ Branch 217 → 218 taken 2021558 times.
✓ Branch 217 → 219 taken 1079059 times.
4677776 file_ptr -> fx_file_current_available_size))
1137 {
1138
1139 /* Skip the following file parameter adjustments. The next write will
1140 detect the logical offset out of the range of the sector and reset
1141 all of the pertinent information. */
1142 2426758 break;
1143 }
1144
1145 /* We need to move to the next logical sector, but first
1146 determine if the next logical sector is within the same
1147 cluster. */
1148
1149 /* Increment the current relative sector in the cluster. */
1150 5954551 file_ptr -> fx_file_current_relative_sector++;
1151
1152 /* Determine if this is in a new cluster. */
1153 5954551 if (file_ptr -> fx_file_current_relative_sector >=
1154
8/8
✓ Branch 90 → 91 taken 53517 times.
✓ Branch 90 → 99 taken 28202 times.
✓ Branch 104 → 105 taken 78209 times.
✓ Branch 104 → 114 taken 42303 times.
✓ Branch 198 → 199 taken 345050 times.
✓ Branch 198 → 208 taken 1930438 times.
✓ Branch 219 → 220 taken 1546194 times.
✓ Branch 219 → 230 taken 1930638 times.
5954551 media_ptr -> fx_media_sectors_per_cluster)
1155 {
1156
1157 /* Yes, we need to move to the next cluster. */
1158
1159 /* Read the FAT entry of the current cluster to find
1160 the next cluster. */
1161 2022970 status = _fx_utility_FAT_entry_read(media_ptr,
1162 file_ptr -> fx_file_current_physical_cluster, &next_cluster);
1163
1164 /* Determine if an error is present. */
1165
16/16
✓ Branch 92 → 93 taken 52032 times.
✓ Branch 92 → 95 taken 1485 times.
✓ Branch 93 → 94 taken 52030 times.
✓ Branch 93 → 95 taken 2 times.
✓ Branch 106 → 107 taken 75940 times.
✓ Branch 106 → 109 taken 2269 times.
✓ Branch 107 → 108 taken 75937 times.
✓ Branch 107 → 109 taken 3 times.
✓ Branch 200 → 201 taken 342617 times.
✓ Branch 200 → 203 taken 2433 times.
✓ Branch 201 → 202 taken 342615 times.
✓ Branch 201 → 203 taken 2 times.
✓ Branch 221 → 222 taken 1543761 times.
✓ Branch 221 → 224 taken 2433 times.
✓ Branch 222 → 223 taken 1543759 times.
✓ Branch 222 → 224 taken 2 times.
2022970 if ((status != FX_SUCCESS) || (next_cluster < FX_FAT_ENTRY_START) ||
1166
8/8
✓ Branch 94 → 95 taken 10959 times.
✓ Branch 94 → 98 taken 41071 times.
✓ Branch 108 → 109 taken 14534 times.
✓ Branch 108 → 113 taken 61403 times.
✓ Branch 202 → 203 taken 10876 times.
✓ Branch 202 → 207 taken 331739 times.
✓ Branch 223 → 224 taken 10876 times.
✓ Branch 223 → 229 taken 1532883 times.
2014341 (next_cluster > media_ptr -> fx_media_fat_reserved))
1167 {
1168 #ifdef FX_ENABLE_FAULT_TOLERANT
1169 26622 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1170 #endif /* FX_ENABLE_FAULT_TOLERANT */
1171
1172 /* Release media protection. */
1173 30117 FX_UNPROTECT
1174
1175 /* Send error message back to caller. */
1176
8/8
✓ Branch 95 → 96 taken 1485 times.
✓ Branch 95 → 97 taken 10961 times.
✓ Branch 110 → 111 taken 2269 times.
✓ Branch 110 → 112 taken 14537 times.
✓ Branch 204 → 205 taken 2433 times.
✓ Branch 204 → 206 taken 10878 times.
✓ Branch 226 → 227 taken 2433 times.
✓ Branch 226 → 228 taken 10878 times.
55874 if (status != FX_SUCCESS)
1177 {
1178 8620 return(status);
1179 }
1180 else
1181 {
1182 47254 return(FX_FILE_CORRUPT);
1183 }
1184 }
1185
1186 /* Otherwise, we have a new cluster. Save it in the file
1187 control block and calculate a new logical sector value. */
1188 1967096 file_ptr -> fx_file_current_physical_cluster = next_cluster;
1189 1967096 file_ptr -> fx_file_current_relative_cluster++;
1190 1967096 file_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
1191 1967096 ((((ULONG64)next_cluster) - FX_FAT_ENTRY_START) *
1192 1967096 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
1193 1967096 file_ptr -> fx_file_current_relative_sector = 0;
1194 }
1195 else
1196 {
1197
1198 /* Still within the same cluster so just increment the
1199 logical sector. */
1200 3931581 file_ptr -> fx_file_current_logical_sector++;
1201 }
1202
1203 /* In either case, we are now positioned at a new sector so
1204 clear the logical sector offset. */
1205 5898677 file_ptr -> fx_file_current_logical_offset = 0;
1206 }
1207 }
1208
1209 #ifdef FX_ENABLE_FAULT_TOLERANT
1210
8/8
✓ Branch 212 → 213 taken 656274 times.
✓ Branch 212 → 230 taken 77154703 times.
✓ Branch 213 → 214 taken 656148 times.
✓ Branch 213 → 230 taken 126 times.
✓ Branch 234 → 235 taken 656783 times.
✓ Branch 234 → 254 taken 80554641 times.
✓ Branch 235 → 236 taken 656657 times.
✓ Branch 235 → 254 taken 126 times.
159022401 if (((replace_clusters > 0) && (data_append == FX_FALSE)) &&
1211
8/8
✓ Branch 214 → 215 taken 974 times.
✓ Branch 214 → 216 taken 655174 times.
✓ Branch 215 → 216 taken 852 times.
✓ Branch 215 → 230 taken 122 times.
✓ Branch 236 → 237 taken 956 times.
✓ Branch 236 → 238 taken 655701 times.
✓ Branch 237 → 238 taken 833 times.
✓ Branch 237 → 254 taken 123 times.
1312805 (file_ptr -> fx_file_current_logical_offset || file_ptr -> fx_file_current_relative_sector))
1212 {
1213
1214 /* Copy sectors in replaced cluster but not overwritten at the end. */
1215
4/4
✓ Branch 216 → 217 taken 852 times.
✓ Branch 216 → 218 taken 655174 times.
✓ Branch 238 → 239 taken 833 times.
✓ Branch 238 → 240 taken 655701 times.
1312560 if (file_ptr -> fx_file_current_logical_offset == 0)
1216 {
1217 1685 i = file_ptr -> fx_file_current_relative_sector;
1218 }
1219 else
1220 {
1221 1310875 i = file_ptr -> fx_file_current_relative_sector + 1;
1222 }
1223
4/4
✓ Branch 229 → 220 taken 1576443 times.
✓ Branch 229 → 230 taken 656020 times.
✓ Branch 253 → 242 taken 1580811 times.
✓ Branch 253 → 254 taken 656528 times.
4469802 for (; i < media_ptr -> fx_media_sectors_per_cluster; i++)
1224 {
1225 3157254 status = _fx_utility_logical_sector_read(media_ptr,
1226 3157254 ((ULONG)media_ptr -> fx_media_data_sector_start) +
1227 3157254 (((ULONG)(copy_tail_cluster - FX_FAT_ENTRY_START)) *
1228 3157254 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + i,
1229 3157254 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
1230
1231 /* Check for good completion status. */
1232
4/4
✓ Branch 221 → 222 taken 4 times.
✓ Branch 221 → 224 taken 1576439 times.
✓ Branch 243 → 244 taken 4 times.
✓ Branch 243 → 247 taken 1580807 times.
3157254 if (status != FX_SUCCESS)
1233 {
1234
1235 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1236
1237 /* Release media protection. */
1238 4 FX_UNPROTECT
1239
1240 /* Return the error status. */
1241 8 return(status);
1242 }
1243
1244 /* Write back the current logical sector. */
1245 3157246 status = _fx_utility_logical_sector_write(media_ptr,
1246 3157246 ((ULONG)media_ptr -> fx_media_data_sector_start) +
1247 3157246 (((ULONG)(file_ptr -> fx_file_current_physical_cluster - FX_FAT_ENTRY_START)) *
1248 3157246 ((ULONG)media_ptr -> fx_media_sectors_per_cluster)) + i,
1249 3157246 media_ptr -> fx_media_memory_buffer, ((ULONG) 1), FX_DATA_SECTOR);
1250
1251 /* Check for good completion status. */
1252
4/4
✓ Branch 225 → 226 taken 2 times.
✓ Branch 225 → 228 taken 1576437 times.
✓ Branch 248 → 249 taken 2 times.
✓ Branch 248 → 252 taken 1580805 times.
3157246 if (status != FX_SUCCESS)
1253 {
1254
1255 4 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1256
1257 /* Release media protection. */
1258 2 FX_UNPROTECT
1259
1260 /* Return the error status. */
1261 4 return(status);
1262 }
1263 }
1264 }
1265 #endif /* FX_ENABLE_FAULT_TOLERANT */
1266
1267 /* Adjust the current file offset accordingly. */
1268 161873795 file_ptr -> fx_file_current_file_offset =
1269 161873795 file_ptr -> fx_file_current_file_offset + size;
1270
1271 /* Copy the new file size into the directory entry. */
1272 161873795 file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size =
1273 161873795 file_ptr -> fx_file_current_file_size;
1274
1275 /* Determine if this write was done past the previous file size. */
1276 161873795 if (file_ptr -> fx_file_current_file_offset >
1277
8/8
✓ Branch 103 → 104 taken 1138484 times.
✓ Branch 103 → 112 taken 114 times.
✓ Branch 118 → 119 taken 1712637 times.
✓ Branch 118 → 127 taken 171 times.
✓ Branch 230 → 231 taken 76972852 times.
✓ Branch 230 → 239 taken 838119 times.
✓ Branch 254 → 255 taken 80373299 times.
✓ Branch 254 → 263 taken 838119 times.
161873795 file_ptr -> fx_file_current_file_size)
1278 {
1279
1280 /* Yes, we have written past the previous end of the file. Update
1281 the file size. */
1282 160197272 file_ptr -> fx_file_current_file_size = file_ptr -> fx_file_current_file_offset;
1283
1284 #ifndef FX_DONT_UPDATE_OPEN_FILES
1285
1286 /* Search the opened files list to see if the same file is opened for reading. */
1287 160197272 open_count = media_ptr -> fx_media_opened_file_count;
1288 160197272 search_ptr = media_ptr -> fx_media_opened_file_list;
1289
8/8
✓ Branch 111 → 105 taken 1779862 times.
✓ Branch 111 → 112 taken 1138484 times.
✓ Branch 126 → 120 taken 2666010 times.
✓ Branch 126 → 127 taken 1712637 times.
✓ Branch 238 → 232 taken 77596680 times.
✓ Branch 238 → 239 taken 76972852 times.
✓ Branch 262 → 256 taken 80997127 times.
✓ Branch 262 → 263 taken 80373299 times.
323236951 while (open_count)
1290 {
1291
1292 /* Is this file the same file opened for reading? */
1293
8/8
✓ Branch 105 → 106 taken 641378 times.
✓ Branch 105 → 110 taken 1138484 times.
✓ Branch 120 → 121 taken 953373 times.
✓ Branch 120 → 125 taken 1712637 times.
✓ Branch 232 → 233 taken 623828 times.
✓ Branch 232 → 237 taken 76972852 times.
✓ Branch 256 → 257 taken 623828 times.
✓ Branch 256 → 261 taken 80373299 times.
163039679 if ((search_ptr != file_ptr) &&
1294 2842407 (search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector ==
1295
8/8
✓ Branch 106 → 107 taken 621170 times.
✓ Branch 106 → 110 taken 20208 times.
✓ Branch 121 → 122 taken 923061 times.
✓ Branch 121 → 125 taken 30312 times.
✓ Branch 233 → 234 taken 603620 times.
✓ Branch 233 → 237 taken 20208 times.
✓ Branch 257 → 258 taken 603620 times.
✓ Branch 257 → 261 taken 20208 times.
2842407 file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector) &&
1296 2751471 (search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset ==
1297
8/8
✓ Branch 107 → 108 taken 157348 times.
✓ Branch 107 → 110 taken 463822 times.
✓ Branch 122 → 123 taken 230226 times.
✓ Branch 122 → 125 taken 692835 times.
✓ Branch 234 → 235 taken 166832 times.
✓ Branch 234 → 237 taken 436788 times.
✓ Branch 258 → 259 taken 166832 times.
✓ Branch 258 → 261 taken 436788 times.
2751471 file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset))
1298 {
1299
1300 /* Yes, the same file is opened for reading. */
1301
1302 /* Setup the new size. */
1303 721238 search_ptr -> fx_file_current_file_size = file_ptr -> fx_file_current_file_offset;
1304
1305 /* Setup the new directory entry. */
1306 721238 search_ptr -> fx_file_dir_entry.fx_dir_entry_cluster = file_ptr -> fx_file_dir_entry.fx_dir_entry_cluster;
1307 721238 search_ptr -> fx_file_dir_entry.fx_dir_entry_file_size = file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size;
1308 721238 search_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector = file_ptr -> fx_file_dir_entry.fx_dir_entry_log_sector;
1309 721238 search_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset = file_ptr -> fx_file_dir_entry.fx_dir_entry_byte_offset;
1310
1311 /* Setup the last cluster. This really isn't used during reading, but it is nice to keep things
1312 consistent. */
1313 721238 search_ptr -> fx_file_last_physical_cluster = file_ptr -> fx_file_last_physical_cluster;
1314
1315 /* Update the available clusters as well. */
1316 721238 search_ptr -> fx_file_current_available_size = file_ptr -> fx_file_current_available_size;
1317
1318 /* Determine if an empty file was previously opened. */
1319
8/8
✓ Branch 108 → 109 taken 20 times.
✓ Branch 108 → 110 taken 157328 times.
✓ Branch 123 → 124 taken 30 times.
✓ Branch 123 → 125 taken 230196 times.
✓ Branch 235 → 236 taken 20 times.
✓ Branch 235 → 237 taken 166812 times.
✓ Branch 259 → 260 taken 20 times.
✓ Branch 259 → 261 taken 166812 times.
721238 if (search_ptr -> fx_file_total_clusters == 0)
1320 {
1321
1322 /* Setup initial parameters. */
1323 90 search_ptr -> fx_file_total_clusters = file_ptr -> fx_file_total_clusters;
1324 90 search_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster;
1325 90 search_ptr -> fx_file_current_relative_cluster = 0;
1326 90 search_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
1327 90 (((ULONG64)(file_ptr -> fx_file_first_physical_cluster - FX_FAT_ENTRY_START)) *
1328 90 ((ULONG)media_ptr -> fx_media_sectors_per_cluster));
1329 90 search_ptr -> fx_file_current_relative_sector = 0;
1330 90 search_ptr -> fx_file_current_logical_offset = 0;
1331 90 search_ptr -> fx_file_current_file_offset = 0;
1332 }
1333 }
1334
1335 /* Adjust the pointer and decrement the search count. */
1336 163039679 search_ptr = search_ptr -> fx_file_opened_next;
1337 163039679 open_count--;
1338 }
1339 #endif
1340 }
1341
1342 /* Finally, mark this file as modified. */
1343 161873795 file_ptr -> fx_file_modified = FX_TRUE;
1344
1345 #ifdef FX_FAULT_TOLERANT_DATA
1346
1347 /* Ensure that all file data is flushed out. */
1348
1349 /* Flush the internal logical sector cache. */
1350 159022389 _fx_utility_logical_sector_flush(media_ptr, 1, media_ptr -> fx_media_total_sectors, FX_FALSE);
1351
1352 /* Lockout interrupts for time/date access. */
1353 81211417 FX_DISABLE_INTS
1354
1355 /* Set the new time and date. */
1356 159022386 file_ptr -> fx_file_dir_entry.fx_dir_entry_time = _fx_system_time;
1357 159022386 file_ptr -> fx_file_dir_entry.fx_dir_entry_date = _fx_system_date;
1358
1359 /* Restore interrupts. */
1360 81211415 FX_RESTORE_INTS
1361
1362 #ifdef FX_ENABLE_FAULT_TOLERANT
1363
4/4
✓ Branch 240 → 241 taken 76667653 times.
✓ Branch 240 → 242 taken 1143318 times.
✓ Branch 266 → 267 taken 80068097 times.
✓ Branch 266 → 268 taken 1143318 times.
159022386 if (media_ptr -> fx_media_fault_tolerant_enabled)
1364 {
1365
1366 /* Copy the new file size into the directory entry. */
1367 156735750 file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size = file_ptr -> fx_file_current_file_size;
1368 }
1369 #endif /* FX_ENABLE_FAULT_TOLERANT */
1370
1371 /* Write the directory entry to the media. */
1372 159022386 status = _fx_directory_entry_write(media_ptr, &(file_ptr -> fx_file_dir_entry));
1373
1374 /* Check for a good status. */
1375
4/4
✓ Branch 243 → 244 taken 22048 times.
✓ Branch 243 → 246 taken 77788923 times.
✓ Branch 269 → 270 taken 22048 times.
✓ Branch 269 → 273 taken 81189367 times.
159022386 if (status != FX_SUCCESS)
1376 {
1377 #ifdef FX_ENABLE_FAULT_TOLERANT
1378 44096 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
1379 #endif /* FX_ENABLE_FAULT_TOLERANT */
1380
1381 /* Release media protection. */
1382 22048 FX_UNPROTECT
1383
1384 /* Error writing the directory. */
1385 44096 return(status);
1386 }
1387 #endif
1388
1389 /* Update the trace event with the bytes written. */
1390 FX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, FX_TRACE_FILE_WRITE, 0, 0, 0, size)
1391
1392 #ifdef FX_ENABLE_FAULT_TOLERANT
1393 /* End transaction. */
1394 158978290 status = _fx_fault_tolerant_transaction_end(media_ptr);
1395
1396 /* Check for a bad status. */
1397
4/4
✓ Branch 247 → 248 taken 3 times.
✓ Branch 247 → 249 taken 77788838 times.
✓ Branch 274 → 275 taken 3 times.
✓ Branch 274 → 277 taken 81189277 times.
158978121 if (status != FX_SUCCESS)
1398 {
1399
1400 /* Release media protection. */
1401 3 FX_UNPROTECT
1402
1403 /* Return the bad status. */
1404 6 return(status);
1405 }
1406
1407 /* Update maximum size used if necessary. */
1408
4/4
✓ Branch 249 → 250 taken 76950749 times.
✓ Branch 249 → 251 taken 838089 times.
✓ Branch 277 → 278 taken 80351188 times.
✓ Branch 277 → 279 taken 838089 times.
158978115 if (file_ptr -> fx_file_current_file_offset > file_ptr -> fx_file_maximum_size_used)
1409 {
1410 157301937 file_ptr -> fx_file_maximum_size_used = file_ptr -> fx_file_current_file_offset;
1411 }
1412 #endif /* FX_ENABLE_FAULT_TOLERANT */
1413
1414 /* Invoke file write callback. */
1415
8/8
✓ Branch 112 → 113 taken 2 times.
✓ Branch 112 → 114 taken 1138596 times.
✓ Branch 127 → 128 taken 3 times.
✓ Branch 127 → 129 taken 1712805 times.
✓ Branch 251 → 252 taken 2 times.
✓ Branch 251 → 253 taken 77788836 times.
✓ Branch 279 → 280 taken 2 times.
✓ Branch 279 → 281 taken 81189275 times.
161829521 if (file_ptr -> fx_file_write_notify)
1416 {
1417 9 file_ptr -> fx_file_write_notify(file_ptr);
1418 }
1419
1420 /* Release media protection. */
1421 82902085 FX_UNPROTECT
1422
1423 /* Return a successful status to the caller. */
1424 161829520 return(FX_SUCCESS);
1425 }
1426
1427