romfs: use hash buckets for FS entry lookups.

* romfs: add hash bucket fields to RomFileSystemContext struct.
* romfs: remove current offset fields from RomFileSystemContext struct and all functions that relied on them.
* romfs: add romfsCalculateEntryHash().
* romfs: update romfsInitializeContext() to also load file/directory hash buckets.
* romfs: update romfsGetTotalDataSize() to make up for the removed functions.
* romfs: update romfsGetChild*EntryByName() functions to use hash bucket lookups.

Other changes include:

* devoptab: add missing exit macros to some FS operations across all interfaces.

* poc: update extractedRomFsReadThreadFunc() to make up for the removed RomFS functions.
This commit is contained in:
Pablo Curiel 2023-12-22 12:20:27 +01:00
parent ef03aa4cbe
commit 364b3f39dc
6 changed files with 130 additions and 119 deletions

View File

@ -4542,6 +4542,7 @@ static void extractedRomFsReadThreadFunc(void *arg)
RomFileSystemContext *romfs_ctx = romfs_thread_data->romfs_ctx;
RomFileSystemFileEntry *romfs_file_entry = NULL;
u64 cur_entry_offset = 0;
char romfs_path[FS_MAX_PATH] = {0}, subdir[0x20] = {0}, *filename = NULL;
size_t filename_len = 0;
@ -4611,11 +4612,8 @@ static void extractedRomFsReadThreadFunc(void *arg)
goto end;
}
/* Reset current file table offset. */
romfsResetFileTableOffset(romfs_ctx);
/* Loop through all file entries. */
while(shared_thread_data->data_written < shared_thread_data->total_size && romfsCanMoveToNextFileEntry(romfs_ctx))
while(shared_thread_data->data_written < shared_thread_data->total_size && cur_entry_offset < romfs_ctx->file_table_size)
{
/* Check if the transfer has been cancelled by the user. */
if (shared_thread_data->transfer_cancelled)
@ -4643,7 +4641,7 @@ static void extractedRomFsReadThreadFunc(void *arg)
}
/* Retrieve RomFS file entry information and generate output path. */
shared_thread_data->read_error = (!(romfs_file_entry = romfsGetCurrentFileEntry(romfs_ctx)) || \
shared_thread_data->read_error = (!(romfs_file_entry = romfsGetFileEntryByOffset(romfs_ctx, cur_entry_offset)) || \
!romfsGeneratePathFromFileEntry(romfs_ctx, romfs_file_entry, romfs_path + filename_len, sizeof(romfs_path) - filename_len, romfs_illegal_char_replace_type));
if (shared_thread_data->read_error)
{
@ -4749,13 +4747,8 @@ static void extractedRomFsReadThreadFunc(void *arg)
if (shared_thread_data->read_error || shared_thread_data->write_error || shared_thread_data->transfer_cancelled) break;
/* Move to the next file entry. */
shared_thread_data->read_error = !romfsMoveToNextFileEntry(romfs_ctx);
if (shared_thread_data->read_error)
{
condvarWakeAll(&g_writeCondvar);
break;
}
/* Get the offset for the next file entry. */
cur_entry_offset += ALIGN_UP(sizeof(RomFileSystemFileEntry) + romfs_file_entry->name_length, ROMFS_TABLE_ENTRY_ALIGNMENT);
}
if (!shared_thread_data->read_error && !shared_thread_data->write_error && !shared_thread_data->transfer_cancelled)

View File

@ -40,12 +40,12 @@ extern "C" {
/// Header used by NCA0 RomFS sections.
typedef struct {
u32 header_size; ///< Header size. Must be equal to ROMFS_OLD_HEADER_SIZE.
u32 directory_bucket_offset; ///< Directory buckets table offset.
u32 directory_bucket_size; ///< Directory buckets table size.
u32 directory_bucket_offset; ///< Directory bucket offset.
u32 directory_bucket_size; ///< Directory bucket size.
u32 directory_entry_offset; ///< Directory entries table offset.
u32 directory_entry_size; ///< Directory entries table size.
u32 file_bucket_offset; ///< File buckets table offset.
u32 file_bucket_size; ///< File buckets table size.
u32 file_bucket_offset; ///< File bucket offset.
u32 file_bucket_size; ///< File bucket size.
u32 file_entry_offset; ///< File entries table offset.
u32 file_entry_size; ///< File entries table size.
u32 body_offset; ///< File data body offset.
@ -56,12 +56,12 @@ NXDT_ASSERT(RomFileSystemInformationOld, ROMFS_OLD_HEADER_SIZE);
/// Header used by NCA2/NCA3 RomFS sections.
typedef struct {
u64 header_size; ///< Header size. Must be equal to ROMFS_HEADER_SIZE.
u64 directory_bucket_offset; ///< Directory buckets table offset.
u64 directory_bucket_size; ///< Directory buckets table size.
u64 directory_bucket_offset; ///< Directory bucket offset.
u64 directory_bucket_size; ///< Directory bucket size.
u64 directory_entry_offset; ///< Directory entries table offset.
u64 directory_entry_size; ///< Directory entries table size.
u64 file_bucket_offset; ///< File buckets table offset.
u64 file_bucket_size; ///< File buckets table size.
u64 file_bucket_offset; ///< File bucket offset.
u64 file_bucket_size; ///< File bucket size.
u64 file_entry_offset; ///< File entries table offset.
u64 file_entry_size; ///< File entries table size.
u64 body_offset; ///< File data body offset.
@ -115,13 +115,15 @@ typedef struct {
u64 offset; ///< RomFS offset (relative to the start of the NCA FS section).
u64 size; ///< RomFS size.
RomFileSystemHeader header; ///< RomFS header.
u64 dir_bucket_size; ///< RomFS directory bucket size.
u32 *dir_bucket; ///< RomFS directory bucket.
u64 dir_table_size; ///< RomFS directory entries table size.
RomFileSystemDirectoryEntry *dir_table; ///< RomFS directory entries table.
u64 file_bucket_size; ///< RomFS file bucket size.
u32 *file_bucket; ///< RomFS file bucket.
u64 file_table_size; ///< RomFS file entries table size.
RomFileSystemFileEntry *file_table; ///< RomFS file entries table.
u64 body_offset; ///< RomFS file data body offset (relative to the start of the RomFS).
u64 cur_dir_offset; ///< Current RomFS directory offset (relative to the start of the directory entries table). Used for RomFS browsing.
u64 cur_file_offset; ///< Current RomFS file offset (relative to the start of the file entries table). Used for RomFS browsing.
} RomFileSystemContext;
typedef struct {
@ -188,28 +190,19 @@ NX_INLINE void romfsFreeContext(RomFileSystemContext *ctx)
if (!ctx) return;
ncaStorageFreeContext(&(ctx->storage_ctx[0]));
ncaStorageFreeContext(&(ctx->storage_ctx[1]));
if (ctx->dir_bucket) free(ctx->dir_bucket);
if (ctx->dir_table) free(ctx->dir_table);
if (ctx->file_bucket) free(ctx->file_bucket);
if (ctx->file_table) free(ctx->file_table);
memset(ctx, 0, sizeof(RomFileSystemContext));
}
/// Functions to reset the current directory/file entry offset.
NX_INLINE void romfsResetDirectoryTableOffset(RomFileSystemContext *ctx)
{
if (ctx) ctx->cur_dir_offset = 0;
}
NX_INLINE void romfsResetFileTableOffset(RomFileSystemContext *ctx)
{
if (ctx) ctx->cur_file_offset = 0;
}
/// Checks if the provided RomFileSystemContext is valid.
NX_INLINE bool romfsIsValidContext(RomFileSystemContext *ctx)
{
return (ctx && ncaStorageIsValidContext(ctx->default_storage_ctx) && ctx->size && ctx->dir_table_size && ctx->dir_table && ctx->file_table_size && ctx->file_table && \
ctx->body_offset >= ctx->header.old_format.header_size && ctx->body_offset < ctx->size);
return (ctx && ncaStorageIsValidContext(ctx->default_storage_ctx) && ctx->size && ctx->dir_bucket_size && ctx->dir_bucket && ctx->dir_table_size && ctx->dir_table && \
ctx->file_bucket_size && ctx->file_bucket && ctx->file_table_size && ctx->file_table && ctx->body_offset >= ctx->header.old_format.header_size && \
ctx->body_offset < ctx->size);
}
/// Functions to retrieve a directory/file entry.
@ -225,60 +218,11 @@ NX_INLINE RomFileSystemDirectoryEntry *romfsGetDirectoryEntryByOffset(RomFileSys
return (ctx ? (RomFileSystemDirectoryEntry*)romfsGetEntryByOffset(ctx, ctx->dir_table, ctx->dir_table_size, sizeof(RomFileSystemDirectoryEntry), dir_entry_offset) : NULL);
}
NX_INLINE RomFileSystemDirectoryEntry *romfsGetCurrentDirectoryEntry(RomFileSystemContext *ctx)
{
return (ctx ? romfsGetDirectoryEntryByOffset(ctx, ctx->cur_dir_offset) : NULL);
}
NX_INLINE RomFileSystemFileEntry *romfsGetFileEntryByOffset(RomFileSystemContext *ctx, u64 file_entry_offset)
{
return (ctx ? (RomFileSystemFileEntry*)romfsGetEntryByOffset(ctx, ctx->file_table, ctx->file_table_size, sizeof(RomFileSystemFileEntry), file_entry_offset) : NULL);
}
NX_INLINE RomFileSystemFileEntry *romfsGetCurrentFileEntry(RomFileSystemContext *ctx)
{
return (ctx ? romfsGetFileEntryByOffset(ctx, ctx->cur_file_offset) : NULL);
}
/// Functions to check if it's possible to move to the next directory/file entry based on the current directory/file entry offset.
NX_INLINE bool romfsCanMoveToNextEntry(RomFileSystemContext *ctx, void *entry_table, u64 entry_table_size, u64 entry_size, u64 entry_offset)
{
if (!romfsIsValidContext(ctx) || !entry_table || !entry_table_size || entry_size < 4 || (entry_offset + entry_size) > entry_table_size) return false;
u32 name_length = *((u32*)((u8*)entry_table + entry_offset + entry_size - 4));
return ((entry_offset + ALIGN_UP(entry_size + name_length, ROMFS_TABLE_ENTRY_ALIGNMENT)) <= entry_table_size);
}
NX_INLINE bool romfsCanMoveToNextDirectoryEntry(RomFileSystemContext *ctx)
{
return (ctx ? romfsCanMoveToNextEntry(ctx, ctx->dir_table, ctx->dir_table_size, sizeof(RomFileSystemDirectoryEntry), ctx->cur_dir_offset) : false);
}
NX_INLINE bool romfsCanMoveToNextFileEntry(RomFileSystemContext *ctx)
{
return (ctx ? romfsCanMoveToNextEntry(ctx, ctx->file_table, ctx->file_table_size, sizeof(RomFileSystemFileEntry), ctx->cur_file_offset) : false);
}
/// Functions to update the current directory/file entry offset to make it point to the next directory/file entry.
NX_INLINE bool romfsMoveToNextEntry(RomFileSystemContext *ctx, void *entry_table, u64 entry_table_size, u64 entry_size, u64 *entry_offset)
{
if (!romfsIsValidContext(ctx) || !entry_table || !entry_table_size || entry_size < 4 || !entry_offset || (*entry_offset + entry_size) > entry_table_size) return false;
u32 name_length = *((u32*)((u8*)entry_table + *entry_offset + entry_size - 4));
*entry_offset += ALIGN_UP(entry_size + name_length, ROMFS_TABLE_ENTRY_ALIGNMENT);
return true;
}
NX_INLINE bool romfsMoveToNextDirectoryEntry(RomFileSystemContext *ctx)
{
return (ctx ? romfsMoveToNextEntry(ctx, ctx->dir_table, ctx->dir_table_size, sizeof(RomFileSystemDirectoryEntry), &(ctx->cur_dir_offset)) : false);
}
NX_INLINE bool romfsMoveToNextFileEntry(RomFileSystemContext *ctx)
{
return (ctx ? romfsMoveToNextEntry(ctx, ctx->file_table, ctx->file_table_size, sizeof(RomFileSystemFileEntry), &(ctx->cur_file_offset)) : false);
}
/// NCA patch management functions.
NX_INLINE void romfsWriteFileEntryPatchToMemoryBuffer(RomFileSystemContext *ctx, RomFileSystemFileEntryPatch *patch, void *buf, u64 buf_size, u64 buf_offset)

View File

@ -22,14 +22,21 @@
#include "nxdt_utils.h"
#include "romfs.h"
/* Helper macros. */
#define ROMFS_ENTRY_OFFSET(entry, table) (u32)((uintptr_t)entry - (uintptr_t)table)
/* Function prototypes. */
static RomFileSystemDirectoryEntry *romfsGetChildDirectoryEntryByName(RomFileSystemContext *ctx, RomFileSystemDirectoryEntry *dir_entry, const char *name);
static RomFileSystemFileEntry *romfsGetChildFileEntryByName(RomFileSystemContext *ctx, RomFileSystemDirectoryEntry *dir_entry, const char *name);
static u32 romfsCalculateEntryHash(RomFileSystemContext *ctx, u32 parent_offset, const char *name, size_t name_len, bool is_file);
bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *base_nca_fs_ctx, NcaFsSectionContext *patch_nca_fs_ctx)
{
u64 dir_table_offset = 0, file_table_offset = 0;
u64 dir_bucket_offset = 0, dir_table_offset = 0;
u64 file_bucket_offset = 0, file_table_offset = 0;
NcaContext *base_nca_ctx = NULL, *patch_nca_ctx = NULL;
bool dump_fs_header = false, success = false;
@ -102,6 +109,30 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *base
goto end;
}
/* Read directory bucket. */
dir_bucket_offset = (is_nca0_romfs ? (u64)out->header.old_format.directory_bucket_offset : out->header.cur_format.directory_bucket_offset);
out->dir_bucket_size = (is_nca0_romfs ? (u64)out->header.old_format.directory_bucket_size : out->header.cur_format.directory_bucket_size);
if (!out->dir_bucket_size || (dir_bucket_offset + out->dir_bucket_size) > out->size)
{
LOG_MSG_ERROR("Invalid RomFS directory bucket!");
dump_fs_header = true;
goto end;
}
out->dir_bucket = malloc(out->dir_bucket_size);
if (!out->dir_bucket)
{
LOG_MSG_ERROR("Unable to allocate memory for RomFS directory bucket!");
goto end;
}
if (!ncaStorageRead(out->default_storage_ctx, out->dir_bucket, out->dir_bucket_size, out->offset + dir_bucket_offset))
{
LOG_MSG_ERROR("Failed to read RomFS directory bucket!");
goto end;
}
/* Read directory entries table. */
dir_table_offset = (is_nca0_romfs ? (u64)out->header.old_format.directory_entry_offset : out->header.cur_format.directory_entry_offset);
out->dir_table_size = (is_nca0_romfs ? (u64)out->header.old_format.directory_entry_size : out->header.cur_format.directory_entry_size);
@ -126,6 +157,30 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *base
goto end;
}
/* Read file bucket. */
file_bucket_offset = (is_nca0_romfs ? (u64)out->header.old_format.file_bucket_offset : out->header.cur_format.file_bucket_offset);
out->file_bucket_size = (is_nca0_romfs ? (u64)out->header.old_format.file_bucket_size : out->header.cur_format.file_bucket_size);
if (!out->file_bucket_size || (file_bucket_offset + out->file_bucket_size) > out->size)
{
LOG_MSG_ERROR("Invalid RomFS file bucket!");
dump_fs_header = true;
goto end;
}
out->file_bucket = malloc(out->file_bucket_size);
if (!out->file_bucket)
{
LOG_MSG_ERROR("Unable to allocate memory for RomFS file bucket!");
goto end;
}
if (!ncaStorageRead(out->default_storage_ctx, out->file_bucket, out->file_bucket_size, out->offset + file_bucket_offset))
{
LOG_MSG_ERROR("Failed to read RomFS file bucket!");
goto end;
}
/* Read file entries table. */
file_table_offset = (is_nca0_romfs ? (u64)out->header.old_format.file_entry_offset : out->header.cur_format.file_entry_offset);
out->file_table_size = (is_nca0_romfs ? (u64)out->header.old_format.file_entry_size : out->header.cur_format.file_entry_size);
@ -219,39 +274,32 @@ bool romfsGetTotalDataSize(RomFileSystemContext *ctx, bool only_updated, u64 *ou
}
RomFileSystemFileEntry *file_entry = NULL;
u64 total_size = 0;
u64 total_size = 0, cur_entry_offset = 0;
bool success = false;
/* Reset current file table offset. */
romfsResetFileTableOffset(ctx);
/* Loop through all file entries. */
while(romfsCanMoveToNextFileEntry(ctx))
while(cur_entry_offset < ctx->file_table_size)
{
bool updated = false;
/* Get current file entry. */
if (!(file_entry = romfsGetCurrentFileEntry(ctx)))
if (!(file_entry = romfsGetFileEntryByOffset(ctx, cur_entry_offset)))
{
LOG_MSG_ERROR("Failed to retrieve current file entry! (0x%lX, 0x%lX).", ctx->cur_file_offset, ctx->file_table_size);
LOG_MSG_ERROR("Failed to retrieve current file entry! (0x%lX, 0x%lX).", cur_entry_offset, ctx->file_table_size);
goto end;
}
/* Update total data size, taking into account the only_updated flag. */
if (only_updated && !romfsIsFileEntryUpdated(ctx, file_entry, &updated))
{
LOG_MSG_ERROR("Failed to determine if file entry is updated or not! (0x%lX, 0x%lX).", ctx->cur_file_offset, ctx->file_table_size);
LOG_MSG_ERROR("Failed to determine if file entry is updated or not! (0x%lX, 0x%lX).", cur_entry_offset, ctx->file_table_size);
goto end;
}
if (!only_updated || (only_updated && updated)) total_size += file_entry->size;
/* Move to the next file entry. */
if (!romfsMoveToNextFileEntry(ctx))
{
LOG_MSG_ERROR("Failed to move to the next file entry! (0x%lX, 0x%lX).", ctx->cur_file_offset, ctx->file_table_size);
goto end;
}
/* Get the offset for the next file entry. */
cur_entry_offset += ALIGN_UP(sizeof(RomFileSystemFileEntry) + file_entry->name_length, ROMFS_TABLE_ENTRY_ALIGNMENT);
}
/* Update output values. */
@ -259,9 +307,6 @@ bool romfsGetTotalDataSize(RomFileSystemContext *ctx, bool only_updated, u64 *ou
success = true;
end:
/* Reset current file table offset. */
romfsResetFileTableOffset(ctx);
return success;
}
@ -667,33 +712,42 @@ bool romfsGenerateFileEntryPatch(RomFileSystemContext *ctx, RomFileSystemFileEnt
static RomFileSystemDirectoryEntry *romfsGetChildDirectoryEntryByName(RomFileSystemContext *ctx, RomFileSystemDirectoryEntry *dir_entry, const char *name)
{
u64 dir_offset = 0;
size_t name_len = 0;
RomFileSystemDirectoryEntry *child_dir_entry = NULL;
u32 hash = 0, parent_offset = 0, dir_offset = 0;
if (!dir_entry || (dir_offset = dir_entry->directory_offset) == ROMFS_VOID_ENTRY || !name || !(name_len = strlen(name)))
if (!dir_entry || !name || !(name_len = strlen(name)))
{
LOG_MSG_ERROR("Invalid parameters!");
return NULL;
}
/* Loop through the child directory entries' linked list. */
/* Calculate hash for the child directory entry. */
parent_offset = ROMFS_ENTRY_OFFSET(dir_entry, ctx->dir_table);
hash = romfsCalculateEntryHash(ctx, parent_offset, name, name_len, false);
//LOG_MSG_DEBUG("parent_offset: 0x%X, parent_name: \"%.*s\", name: \"%s\", hash: 0x%X", parent_offset, (int)dir_entry->name_length, dir_entry->name, name, hash);
/* Perform lookup using the directory bucket. */
dir_offset = ctx->dir_bucket[hash];
while(dir_offset != ROMFS_VOID_ENTRY)
{
/* Get current directory entry. */
if (!(child_dir_entry = romfsGetDirectoryEntryByOffset(ctx, dir_offset)))
{
LOG_MSG_ERROR("Failed to retrieve directory entry! (0x%lX, 0x%lX).", dir_offset, ctx->dir_table_size);
LOG_MSG_ERROR("Failed to retrieve directory entry! (0x%X, 0x%lX).", dir_offset, ctx->dir_table_size);
break;
}
//LOG_MSG_DEBUG("offset: 0x%X, parent: 0x%X, name: \"%.*s\"", dir_offset, child_dir_entry->parent_offset, (int)child_dir_entry->name_length, child_dir_entry->name);
/* Check if we found the right child directory entry. */
/* strncmp() is used here instead of strcmp() because names stored in RomFS sections are not always NULL terminated. */
/* If the name ends at a 4-byte boundary, the next entry starts immediately. */
if (child_dir_entry->name_length == name_len && !strncmp(child_dir_entry->name, name, name_len)) return child_dir_entry;
if (child_dir_entry->parent_offset == parent_offset && child_dir_entry->name_length == name_len && !strncmp(child_dir_entry->name, name, name_len)) return child_dir_entry;
/* Update current directory entry offset. */
dir_offset = child_dir_entry->next_offset;
dir_offset = child_dir_entry->bucket_offset;
}
return NULL;
@ -701,33 +755,53 @@ static RomFileSystemDirectoryEntry *romfsGetChildDirectoryEntryByName(RomFileSys
static RomFileSystemFileEntry *romfsGetChildFileEntryByName(RomFileSystemContext *ctx, RomFileSystemDirectoryEntry *dir_entry, const char *name)
{
u64 file_offset = 0;
size_t name_len = 0;
RomFileSystemFileEntry *child_file_entry = NULL;
u32 hash = 0, parent_offset = 0, file_offset = 0;
if (!dir_entry || (file_offset = dir_entry->file_offset) == ROMFS_VOID_ENTRY || !name || !(name_len = strlen(name)))
if (!dir_entry || !name || !(name_len = strlen(name)))
{
LOG_MSG_ERROR("Invalid parameters!");
return NULL;
}
/* Loop through the child file entries' linked list. */
/* Calculate hash for the child file entry. */
parent_offset = ROMFS_ENTRY_OFFSET(dir_entry, ctx->dir_table);
hash = romfsCalculateEntryHash(ctx, parent_offset, name, name_len, true);
//LOG_MSG_DEBUG("parent_offset: 0x%X, parent_name: \"%.*s\", name: \"%s\", hash: 0x%X", parent_offset, (int)dir_entry->name_length, dir_entry->name, name, hash);
/* Perform lookup using the file bucket. */
file_offset = ctx->file_bucket[hash];
while(file_offset != ROMFS_VOID_ENTRY)
{
/* Get current file entry. */
if (!(child_file_entry = romfsGetFileEntryByOffset(ctx, file_offset)))
{
LOG_MSG_ERROR("Failed to retrieve file entry! (0x%lX, 0x%lX).", file_offset, ctx->file_table_size);
LOG_MSG_ERROR("Failed to retrieve file entry! (0x%X, 0x%lX).", file_offset, ctx->file_table_size);
break;
}
//LOG_MSG_DEBUG("offset: 0x%X, parent: 0x%X, name: \"%.*s\"", file_offset, child_file_entry->parent_offset, (int)child_file_entry->name_length, child_file_entry->name);
/* Check if we found the right child file entry. */
/* strncmp() is used here instead of strcmp() because names stored in RomFS sections are not always NULL terminated. */
/* If the name ends at a 4-byte boundary, the next entry starts immediately. */
if (child_file_entry->name_length == name_len && !strncmp(child_file_entry->name, name, name_len)) return child_file_entry;
if (child_file_entry->parent_offset == parent_offset && child_file_entry->name_length == name_len && !strncmp(child_file_entry->name, name, name_len)) return child_file_entry;
file_offset = child_file_entry->next_offset;
/* Update current file entry offset. */
file_offset = child_file_entry->bucket_offset;
}
return NULL;
}
static u32 romfsCalculateEntryHash(RomFileSystemContext *ctx, u32 parent_offset, const char *name, size_t name_len, bool is_file)
{
u32 hash = (parent_offset ^ 123456789);
u32 total = ((u32)(is_file ? ctx->file_bucket_size : ctx->dir_bucket_size) / sizeof(u32));
for(size_t i = 0; i < name_len; i++) hash = (((hash >> 5) | (hash << 27)) ^ name[i]);
return (hash % total);
}

View File

@ -248,7 +248,7 @@ static int hfsdev_stat(struct _reent *r, const char *file, struct stat *st)
LOG_MSG_DEBUG("Getting file stats for \"%s:/%s\".", dev_ctx->name, file);
/* Get information about the requested Hash FS entry. */
if (!hfsGetEntryIndexByName(fs_ctx, file, &index) || !(hfs_entry = hfsGetEntryByIndex(fs_ctx, index))) DEVOPTAB_SET_ERROR(ENOENT);
if (!hfsGetEntryIndexByName(fs_ctx, file, &index) || !(hfs_entry = hfsGetEntryByIndex(fs_ctx, index))) DEVOPTAB_SET_ERROR_AND_EXIT(ENOENT);
/* Fill stat info. */
hfsdev_fill_stat(st, index, hfs_entry, dev_ctx->mount_time);

View File

@ -254,7 +254,7 @@ static int romfsdev_stat(struct _reent *r, const char *file, struct stat *st)
LOG_MSG_DEBUG("Getting file stats for \"%s:%s\".", dev_ctx->name, file);
/* Get information about the requested RomFS file entry. */
if (!(file_entry = romfsGetFileEntryByPath(fs_ctx, file))) DEVOPTAB_SET_ERROR(ENOENT);
if (!(file_entry = romfsGetFileEntryByPath(fs_ctx, file))) DEVOPTAB_SET_ERROR_AND_EXIT(ENOENT);
/* Fill stat info. */
romfsdev_fill_file_stat(st, fs_ctx, file_entry, dev_ctx->mount_time);
@ -280,7 +280,7 @@ static DIR_ITER *romfsdev_diropen(struct _reent *r, DIR_ITER *dirState, const ch
memset(dir, 0, sizeof(RomFileSystemDirectoryState));
/* Get information about the requested RomFS directory entry. */
if (!(dir->dir_entry = romfsGetDirectoryEntryByPath(fs_ctx, path))) DEVOPTAB_SET_ERROR(ENOENT);
if (!(dir->dir_entry = romfsGetDirectoryEntryByPath(fs_ctx, path))) DEVOPTAB_SET_ERROR_AND_EXIT(ENOENT);
dir->cur_dir_offset = dir->dir_entry->directory_offset;
dir->cur_file_offset = dir->dir_entry->file_offset;

View File

@ -248,7 +248,7 @@ static int pfsdev_stat(struct _reent *r, const char *file, struct stat *st)
LOG_MSG_DEBUG("Getting file stats for \"%s:/%s\".", dev_ctx->name, file);
/* Get information about the requested Partition FS entry. */
if (!pfsGetEntryIndexByName(fs_ctx, file, &index) || !(pfs_entry = pfsGetEntryByIndex(fs_ctx, index))) DEVOPTAB_SET_ERROR(ENOENT);
if (!pfsGetEntryIndexByName(fs_ctx, file, &index) || !(pfs_entry = pfsGetEntryByIndex(fs_ctx, index))) DEVOPTAB_SET_ERROR_AND_EXIT(ENOENT);
/* Fill stat info. */
pfsdev_fill_stat(st, index, pfs_entry, dev_ctx->mount_time);