From 0161b93d50d6915116c4ca9d1cad42ef89a4ad9e Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 3 Mar 2020 19:23:53 +0100 Subject: imfs: Replace devfs with an IMFS specialization Add a simplified path evaluation function IMFS_eval_path_devfs() for a device only IMFS configuration. The code size can be further reduced by the application if it disables the support for legacy IO drivers via: #define CONFIGURE_IMFS_DISABLE_MKNOD #define CONFIGURE_IMFS_DISABLE_MKNOD_DEVICE Obsolete CONFIGURE_MAXIMUM_DEVICES. Remove BSP_MAXIMUM_DEVICES. Update #3894. Update #3898. --- cpukit/libfs/src/imfs/imfs_eval_devfs.c | 163 ++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 cpukit/libfs/src/imfs/imfs_eval_devfs.c (limited to 'cpukit/libfs/src/imfs') diff --git a/cpukit/libfs/src/imfs/imfs_eval_devfs.c b/cpukit/libfs/src/imfs/imfs_eval_devfs.c new file mode 100644 index 0000000000..d25e4ff8e2 --- /dev/null +++ b/cpukit/libfs/src/imfs/imfs_eval_devfs.c @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup ClassicIO + * + * @brief Implementation of IMFS_eval_path_devfs(). + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +typedef struct { + uint8_t len; + char name[3]; +} IMFS_devfs_dir; + +static const IMFS_devfs_dir IMFS_devfs_dirs[] = { + { .len = 1, .name = { '/' } }, + { .len = 1, .name = { '.' } }, + { .len = 2, .name = { '.', '.' } }, + { .len = 3, .name = { 'd', 'e', 'v' } } +}; + +static IMFS_jnode_t *IMFS_devfs_is_dir( + rtems_filesystem_eval_path_context_t *ctx, + IMFS_directory_t *dir +) +{ + const char *path; + size_t pathlen; + size_t i; + + path = rtems_filesystem_eval_path_get_path( ctx ); + pathlen = rtems_filesystem_eval_path_get_pathlen( ctx ); + + for ( i = 0; i < RTEMS_ARRAY_SIZE( IMFS_devfs_dirs ); ++i ) { + bool match; + + match = IMFS_devfs_dirs[ i ].len == pathlen + && memcmp( IMFS_devfs_dirs[ i ].name, path, pathlen ) == 0; + + if ( match ) { + int eval_flags; + + eval_flags = rtems_filesystem_eval_path_get_flags( ctx ); + eval_flags &= ~RTEMS_FS_EXCLUSIVE; + rtems_filesystem_eval_path_set_flags( ctx, eval_flags ); + rtems_filesystem_eval_path_clear_path( ctx ); + return &dir->Node; + } + } + + return NULL; +} + +static IMFS_jnode_t *IMFS_devfs_search( + rtems_filesystem_eval_path_context_t *ctx, + IMFS_directory_t *dir +) +{ + const char *path; + size_t pathlen; + rtems_chain_control *entries; + rtems_chain_node *current; + rtems_chain_node *tail; + + path = rtems_filesystem_eval_path_get_path( ctx ); + pathlen = rtems_filesystem_eval_path_get_pathlen( ctx ); + entries = &dir->Entries; + current = rtems_chain_first( entries ); + tail = rtems_chain_tail( entries ); + + while ( current != tail ) { + IMFS_jnode_t *entry; + bool match; + + entry = (IMFS_jnode_t *) current; + match = entry->namelen == pathlen + && memcmp( entry->name, path, pathlen ) == 0; + + if ( match ) { + return entry; + } + + current = rtems_chain_next( current ); + } + + return NULL; +} + +void IMFS_eval_path_devfs( rtems_filesystem_eval_path_context_t *ctx ) +{ + rtems_filesystem_location_info_t *currentloc; + IMFS_directory_t *dir; + IMFS_jnode_t *entry; + + currentloc = rtems_filesystem_eval_path_get_currentloc( ctx ); + dir = currentloc->node_access; + + entry = IMFS_devfs_is_dir( ctx, dir ); + + if ( entry != NULL ) { + return; + } + + entry = IMFS_devfs_search( ctx, dir ); + + if ( entry != NULL ) { + int eval_flags; + + eval_flags = rtems_filesystem_eval_path_get_flags( ctx ); + + if ( ( eval_flags & RTEMS_FS_EXCLUSIVE ) == 0 ) { + --dir->Node.reference_count; + ++entry->reference_count; + currentloc->node_access = entry; + currentloc->node_access_2 = IMFS_generic_get_context_by_node( entry ); + IMFS_Set_handlers( currentloc ); + rtems_filesystem_eval_path_clear_path( ctx ); + } else { + rtems_filesystem_eval_path_error( ctx, EEXIST ); + } + } else { + rtems_filesystem_eval_path_set_token( + ctx, + rtems_filesystem_eval_path_get_path( ctx ), + rtems_filesystem_eval_path_get_pathlen( ctx ) + ); + rtems_filesystem_eval_path_clear_path( ctx ); + } +} -- cgit v1.2.3