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