mirror of
https://github.com/eclipse-threadx/filex.git
synced 2026-09-14 20:55:36 +08:00
Transition FileX to Eclipse Fundation
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** FileX Component */
|
||||
/** */
|
||||
/** Fault Tolerant */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define FX_SOURCE_CODE
|
||||
|
||||
#include "fx_api.h"
|
||||
#include "fx_utility.h"
|
||||
#include "fx_fault_tolerant.h"
|
||||
|
||||
|
||||
#ifdef FX_ENABLE_FAULT_TOLERANT
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _fx_fault_tolerant_apply_logs PORTABLE C */
|
||||
/* 6.2.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function applies changes to the file system. The changes are */
|
||||
/* already recorded in the fault tolerant log file. Therefore this */
|
||||
/* function reads the content of the log entries and apply these */
|
||||
/* changes to the file system. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* media_ptr Media control block pointer */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* return status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _fx_utility_logical_sector_write Write a logical sector */
|
||||
/* _fx_utility_logical_sector_read Read a logical sector */
|
||||
/* _fx_utility_16_unsigned_read Read a USHORT from memory */
|
||||
/* _fx_utility_32_unsigned_read Read a ULONG from memory */
|
||||
/* _fx_utility_64_unsigned_read Read a ULONG64 from memory */
|
||||
/* _fx_utility_FAT_entry_write Write a FAT entry */
|
||||
/* _fx_fault_tolerant_cleanup_FAT_chain Cleanup FAT chain */
|
||||
/* memcpy Memory Copy */
|
||||
/* _fx_utility_FAT_flush Flush written FAT entries */
|
||||
/* _fx_utility_logical_sector_flush Flush written logical sectors */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _fx_fault_tolerant_enable */
|
||||
/* _fx_fault_tolerant_transaction_end */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 William E. Lamie Modified comment(s), verified */
|
||||
/* memcpy usage, */
|
||||
/* resulting in version 6.1 */
|
||||
/* 10-31-2022 Tiejun Zhou Modified comment(s), fixed */
|
||||
/* overflow in log size check, */
|
||||
/* resulting in version 6.2.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _fx_fault_tolerant_apply_logs(FX_MEDIA *media_ptr)
|
||||
{
|
||||
UINT status;
|
||||
ULONG64 log_sector;
|
||||
ULONG remaining_logs;
|
||||
ULONG copy_size;
|
||||
ULONG copy_offset;
|
||||
UCHAR *current_ptr;
|
||||
ULONG size;
|
||||
USHORT log_type;
|
||||
ULONG log_len;
|
||||
FX_FAULT_TOLERANT_LOG_HEADER *log_header;
|
||||
FX_FAULT_TOLERANT_FAT_CHAIN *FAT_chain;
|
||||
FX_FAULT_TOLERANT_LOG_CONTENT *log_content;
|
||||
FX_FAULT_TOLERANT_FAT_LOG *fat_log;
|
||||
FX_FAULT_TOLERANT_DIR_LOG *dir_log;
|
||||
|
||||
/* Set log header, FAT chain and log content pointer. */
|
||||
log_header = (FX_FAULT_TOLERANT_LOG_HEADER *)media_ptr -> fx_media_fault_tolerant_memory_buffer;
|
||||
FAT_chain = (FX_FAULT_TOLERANT_FAT_CHAIN *)(media_ptr -> fx_media_fault_tolerant_memory_buffer + FX_FAULT_TOLERANT_FAT_CHAIN_OFFSET);
|
||||
log_content = (FX_FAULT_TOLERANT_LOG_CONTENT *)(media_ptr -> fx_media_fault_tolerant_memory_buffer +
|
||||
FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET);
|
||||
|
||||
/* Find the size of the log file. */
|
||||
size = _fx_utility_16_unsigned_read((UCHAR *)&log_header -> fx_fault_tolerant_log_header_total_size);
|
||||
|
||||
/* Extended port-specific processing macro, which is by default defined to white space. */
|
||||
FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION
|
||||
|
||||
size -= FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE;
|
||||
|
||||
/* Find the number of log entries. */
|
||||
remaining_logs = _fx_utility_16_unsigned_read((UCHAR *)&log_content -> fx_fault_tolerant_log_content_count);
|
||||
|
||||
/* Get start address of logs. */
|
||||
current_ptr = (UCHAR *)log_content + FX_FAULT_TOLERANT_LOG_CONTENT_HEADER_SIZE;
|
||||
|
||||
/* Loop through all the logs to apply the changes. */
|
||||
while (remaining_logs)
|
||||
{
|
||||
|
||||
/* Obtain log type of this entry. */
|
||||
log_type = (USHORT)_fx_utility_16_unsigned_read(current_ptr);
|
||||
|
||||
/* Read log length. */
|
||||
log_len = _fx_utility_16_unsigned_read(current_ptr + 2);
|
||||
|
||||
|
||||
/* Validate log entry size. */
|
||||
if (log_len > size)
|
||||
{
|
||||
|
||||
/* Something wrong with log file. */
|
||||
return(FX_FILE_CORRUPT);
|
||||
}
|
||||
|
||||
/* Reduce the total log file size. */
|
||||
size -= log_len;
|
||||
|
||||
/* Process log entry by type. */
|
||||
switch (log_type)
|
||||
{
|
||||
case FX_FAULT_TOLERANT_FAT_LOG_TYPE:
|
||||
|
||||
/* This is a FAT log. */
|
||||
fat_log = (FX_FAULT_TOLERANT_FAT_LOG *)current_ptr;
|
||||
|
||||
/* Write FAT entry. */
|
||||
status = _fx_utility_FAT_entry_write(media_ptr,
|
||||
_fx_utility_32_unsigned_read((UCHAR *)&fat_log -> fx_fault_tolerant_FAT_log_cluster),
|
||||
_fx_utility_32_unsigned_read((UCHAR *)&fat_log -> fx_fault_tolerant_FAT_log_value));
|
||||
|
||||
if (status != FX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return the error status. */
|
||||
return(status);
|
||||
}
|
||||
break;
|
||||
|
||||
case FX_FAULT_TOLERANT_DIR_LOG_TYPE:
|
||||
|
||||
/* This is a DIR log. */
|
||||
dir_log = (FX_FAULT_TOLERANT_DIR_LOG *)current_ptr;
|
||||
|
||||
log_sector = _fx_utility_64_unsigned_read((UCHAR *)&dir_log -> fx_fault_tolerant_dir_log_sector);
|
||||
|
||||
/* Get the destination sector. */
|
||||
status = _fx_utility_logical_sector_read(media_ptr,
|
||||
log_sector,
|
||||
media_ptr -> fx_media_memory_buffer,
|
||||
((ULONG) 1), FX_DATA_SECTOR);
|
||||
|
||||
if (status != FX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return the error status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
/* Set copy information. */
|
||||
copy_offset = _fx_utility_32_unsigned_read((UCHAR *)&dir_log -> fx_fault_tolerant_dir_log_offset);
|
||||
|
||||
|
||||
copy_size = log_len - FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE;
|
||||
|
||||
if (((ULONG64)copy_offset + (ULONG64)copy_size) > (ULONG64)(media_ptr -> fx_media_memory_size))
|
||||
{
|
||||
return(FX_FILE_CORRUPT);
|
||||
}
|
||||
|
||||
/* Copy data into destination sector. */
|
||||
memcpy(media_ptr -> fx_media_memory_buffer + copy_offset, /* Use case of memcpy is verified. */
|
||||
current_ptr + FX_FAULT_TOLERANT_DIR_LOG_ENTRY_SIZE, copy_size);
|
||||
|
||||
|
||||
/* Write back the current logical sector. */
|
||||
status = _fx_utility_logical_sector_write(media_ptr,
|
||||
log_sector,
|
||||
media_ptr -> fx_media_memory_buffer,
|
||||
((ULONG) 1), FX_DIRECTORY_SECTOR);
|
||||
|
||||
if (status != FX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return the error status. */
|
||||
return(status);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Wrong type. */
|
||||
return(FX_SECTOR_INVALID);
|
||||
}
|
||||
|
||||
/* Decrement the remaining log counter. */
|
||||
remaining_logs--;
|
||||
|
||||
/* Move to start position of next log entry. */
|
||||
current_ptr += log_len;
|
||||
}
|
||||
|
||||
/* Check whether or not to process FAT chain. */
|
||||
if (FAT_chain -> fx_fault_tolerant_FAT_chain_flag & FX_FAULT_TOLERANT_FLAG_FAT_CHAIN_VALID)
|
||||
{
|
||||
|
||||
/* Free old link of FAT. */
|
||||
status = _fx_fault_tolerant_cleanup_FAT_chain(media_ptr, FX_FAULT_TOLERANT_FAT_CHAIN_CLEANUP);
|
||||
if (status != FX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return the error status. */
|
||||
return(status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush the internal logical sector cache. */
|
||||
status = _fx_utility_logical_sector_flush(media_ptr, 1, (ULONG64) media_ptr -> fx_media_total_sectors, FX_FALSE);
|
||||
|
||||
/* Check for a bad status. */
|
||||
if (status != FX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return the bad status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
/* Flush FAT table. */
|
||||
#ifdef FX_FAULT_TOLERANT
|
||||
|
||||
/* Ensure the new FAT chain is properly written to the media. */
|
||||
|
||||
/* Flush the cached individual FAT entries */
|
||||
_fx_utility_FAT_flush(media_ptr);
|
||||
#endif
|
||||
|
||||
/* Return success. */
|
||||
return(FX_SUCCESS);
|
||||
}
|
||||
#endif /* FX_ENABLE_FAULT_TOLERANT */
|
||||
|
||||
Reference in New Issue
Block a user