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_directory_sector PORTABLE C */
35 /* 6.1 */
36 /* AUTHOR */
37 /* */
38 /* William E. Lamie, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* This function handles directory sector read requests. During file or*/
43 /* directory operations with Fault Tolerant protection, intermediate */
44 /* operations are written to the fault tolerant log files. Therefore, */
45 /* sector read should search for fault tolerant log before the request */
46 /* can be passed to normal directory entry read routine. */
47 /* */
48 /* INPUT */
49 /* */
50 /* media_ptr Media control block pointer */
51 /* logical_sector Logical sector number */
52 /* buffer_ptr Pointer of receiving buffer */
53 /* sectors Number of sectors to read */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* return status */
58 /* */
59 /* CALLS */
60 /* */
61 /* _fx_utility_16_unsigned_read Read a USHORT from memory */
62 /* _fx_utility_32_unsigned_read Read a ULONG from memory */
63 /* memcpy Memory Copy */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* _fx_utility_logical_sector_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), verified */
75 /* memcpy usage, */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_fx_fault_tolerant_read_directory_sector(FX_MEDIA * media_ptr,ULONG64 logical_sector,VOID * buffer_ptr,ULONG64 sectors)79 UINT _fx_fault_tolerant_read_directory_sector(FX_MEDIA *media_ptr, ULONG64 logical_sector,
80 VOID *buffer_ptr, ULONG64 sectors)
81 {
82 ULONG logs_remaining;
83 ULONG copy_offset;
84 ULONG copy_size;
85 UCHAR *current_ptr;
86 UCHAR *current_buffer_ptr;
87 ULONG size;
88 USHORT type;
89 ULONG log_len;
90 ULONG64 log_sector;
91 FX_FAULT_TOLERANT_DIR_LOG *dir_log;
92
93 /* Get fault tolerant data. */
94 logs_remaining = media_ptr -> fx_media_fault_tolerant_total_logs;
95
96 /* Any redo logs? */
97 if (logs_remaining == 0)
98 {
99
100 /* No. Just return. */
101 return(FX_SUCCESS);
102 }
103
104 /* Get size of all logs. */
105 size = media_ptr -> fx_media_fault_tolerant_file_size - FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET;
106
107 /* Get the first log pointer. */
108 current_ptr = media_ptr -> fx_media_fault_tolerant_memory_buffer +
109 FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET +
110 FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE;
111
112 /* Loop throught all FAT logs. */
113 while (logs_remaining)
114 {
115
116 /* Check log type. */
117 type = (USHORT)_fx_utility_16_unsigned_read(current_ptr);
118
119 /* Get log length. */
120 log_len = _fx_utility_16_unsigned_read(current_ptr + 2);
121
122 /* Validate the size value. */
123 if (log_len > size)
124 {
125
126 /* Log file is corrupted. Nothing can be done. Return.*/
127 return(FX_FILE_CORRUPT);
128 }
129 size -= log_len;
130
131 /* Check log type. */
132 if (type == FX_FAULT_TOLERANT_DIR_LOG_TYPE)
133 {
134
135 /* Get the log pointer. */
136 dir_log = (FX_FAULT_TOLERANT_DIR_LOG *)current_ptr;
137
138 /* Get the sector of log. */
139 log_sector = _fx_utility_64_unsigned_read((UCHAR *)&dir_log -> fx_fault_tolerant_dir_log_sector);
140
141 /* Is this log sector in the range of sectors to read? */
142 if ((log_sector >= logical_sector) && (log_sector < logical_sector + sectors))
143 {
144
145 /* Yes. Update the content in this sector. */
146 current_buffer_ptr = ((UCHAR *)buffer_ptr) + (log_sector - logical_sector) *
147 media_ptr -> fx_media_bytes_per_sector;
148
149 /* Set copy information. */
150 copy_offset = _fx_utility_32_unsigned_read((UCHAR *)&dir_log -> fx_fault_tolerant_dir_log_offset);
151
152 copy_size = log_len - FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE;
153
154 if ((copy_offset + copy_size) > media_ptr -> fx_media_bytes_per_sector)
155 {
156 return(FX_FILE_CORRUPT);
157 }
158
159 /* Copy data into destination sector. */
160 memcpy(current_buffer_ptr + copy_offset, /* Use case of memcpy is verified. */
161 current_ptr + FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE, copy_size);
162 }
163 }
164
165 /* Decrease the logs_remaining counter. */
166 logs_remaining--;
167
168 /* Move to start position of next log entry. */
169 current_ptr += log_len;
170 }
171
172 /* Return success. */
173 return(FX_SUCCESS);
174 }
175
176 #endif /* FX_ENABLE_FAULT_TOLERANT */
177
178