1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** FileX Component */
16 /** */
17 /** Fault Tolerant */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define FX_SOURCE_CODE
23
24 #include "fx_api.h"
25 #include "fx_utility.h"
26 #include "fx_fault_tolerant.h"
27
28
29 #ifdef FX_ENABLE_FAULT_TOLERANT
30 /**************************************************************************/
31 /* */
32 /* FUNCTION RELEASE */
33 /* */
34 /* _fx_fault_tolerant_read_FAT PORTABLE C */
35 /* 6.1 */
36 /* AUTHOR */
37 /* */
38 /* William E. Lamie, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* This function reads value of a FAT entry from log file if it */
43 /* exists. During file or directory operations with Fault Tolerant */
44 /* protection, intermediate operations are written to the fault */
45 /* tolerant log files. Therefore, FAT-entry read should search for */
46 /* fault tolerant log before the request can be passed to normal FAT */
47 /* entry read routine. */
48 /* */
49 /* INPUT */
50 /* */
51 /* media_ptr Media control block pointer */
52 /* cluster Cluster entry number */
53 /* value Pointer to value for the entry*/
54 /* log_type FAT or bitmap */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* return status */
59 /* */
60 /* CALLS */
61 /* */
62 /* _fx_utility_16_unsigned_read Read a USHORT from memory */
63 /* _fx_utility_32_unsigned_read Read a ULONG from memory */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* _fx_utility_FAT_entry_read */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
74 /* 09-30-2020 William E. Lamie Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* */
77 /**************************************************************************/
_fx_fault_tolerant_read_FAT(FX_MEDIA * media_ptr,ULONG cluster,ULONG * value,ULONG log_type)78 UINT _fx_fault_tolerant_read_FAT(FX_MEDIA *media_ptr, ULONG cluster, ULONG *value, ULONG log_type)
79 {
80 ULONG logs_remaining;
81 UCHAR *current_ptr;
82 UCHAR found = FX_FALSE;
83 ULONG size;
84 USHORT type;
85 ULONG log_len;
86 FX_FAULT_TOLERANT_FAT_LOG *fat_log;
87
88
89 /* Get fault tolerant data. */
90 logs_remaining = media_ptr -> fx_media_fault_tolerant_total_logs;
91
92 /* Any redo logs? */
93 if (logs_remaining == 0)
94 {
95
96 /* No. Just return. */
97 return(FX_READ_CONTINUE);
98 }
99
100 /* Get size of all logs. */
101 size = media_ptr -> fx_media_fault_tolerant_file_size - FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET;
102
103 /* Get the first log pointer. */
104 current_ptr = media_ptr -> fx_media_fault_tolerant_memory_buffer +
105 FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET +
106 FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE;
107
108 /* Loop throught all FAT logs. */
109 while (logs_remaining)
110 {
111
112 /* Check log type. */
113 type = (USHORT)_fx_utility_16_unsigned_read(current_ptr);
114
115 /* Get log length. */
116 log_len = _fx_utility_16_unsigned_read(current_ptr + 2);
117
118 /* Validate the size value. */
119 if (log_len > size)
120 {
121
122 /* Log file is corrupted. Nothing can be done. Return.*/
123 return(FX_FILE_CORRUPT);
124 }
125 size -= log_len;
126
127 /* Check log type. */
128 if (type == log_type)
129 {
130
131 /* This is the log with same type . */
132 /* Get the log pointer. */
133 fat_log = (FX_FAULT_TOLERANT_FAT_LOG *)current_ptr;
134
135 /* Is this FAT log entry the one looking for? */
136 if (_fx_utility_32_unsigned_read((UCHAR *)&fat_log -> fx_fault_tolerant_FAT_log_cluster) == cluster)
137 {
138
139 /* Yes, it is. */
140 *value = _fx_utility_32_unsigned_read((UCHAR *)&fat_log -> fx_fault_tolerant_FAT_log_value);
141
142 /* Do not return since there may be more than one log for this cluster. */
143 found = FX_TRUE;
144 }
145 }
146
147 /* Decrease the logs_remaining counter. */
148 logs_remaining--;
149
150 /* Get next log pointer. */
151 current_ptr += log_len;
152 }
153
154 if (found != FX_TRUE)
155 {
156
157 /* Pass the request to FAT entry read. */
158 return(FX_READ_CONTINUE);
159 }
160
161 /* Return success. */
162 return(FX_SUCCESS);
163 }
164
165 #endif /* FX_ENABLE_FAULT_TOLERANT */
166
167