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