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/devfs/devclose.c | 29 ------ cpukit/libfs/src/devfs/devfs_eval.c | 95 ------------------- cpukit/libfs/src/devfs/devfs_init.c | 79 ---------------- cpukit/libfs/src/devfs/devfs_mknod.c | 63 ------------ cpukit/libfs/src/devfs/devfs_show.c | 51 ---------- cpukit/libfs/src/devfs/devioctl.c | 31 ------ cpukit/libfs/src/devfs/devopen.c | 39 -------- cpukit/libfs/src/devfs/devread.c | 31 ------ cpukit/libfs/src/devfs/devstat.c | 36 ------- cpukit/libfs/src/devfs/devwrite.c | 31 ------ cpukit/libfs/src/imfs/imfs_eval_devfs.c | 163 ++++++++++++++++++++++++++++++++ 11 files changed, 163 insertions(+), 485 deletions(-) delete mode 100644 cpukit/libfs/src/devfs/devclose.c delete mode 100644 cpukit/libfs/src/devfs/devfs_eval.c delete mode 100644 cpukit/libfs/src/devfs/devfs_init.c delete mode 100644 cpukit/libfs/src/devfs/devfs_mknod.c delete mode 100644 cpukit/libfs/src/devfs/devfs_show.c delete mode 100644 cpukit/libfs/src/devfs/devioctl.c delete mode 100644 cpukit/libfs/src/devfs/devopen.c delete mode 100644 cpukit/libfs/src/devfs/devread.c delete mode 100644 cpukit/libfs/src/devfs/devstat.c delete mode 100644 cpukit/libfs/src/devfs/devwrite.c create mode 100644 cpukit/libfs/src/imfs/imfs_eval_devfs.c (limited to 'cpukit/libfs/src') diff --git a/cpukit/libfs/src/devfs/devclose.c b/cpukit/libfs/src/devfs/devclose.c deleted file mode 100644 index e3ca969988..0000000000 --- a/cpukit/libfs/src/devfs/devclose.c +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @file - * - * @brief Maps Close Operation to rtems_io_close - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -int devFS_close( - rtems_libio_t *iop -) -{ - const devFS_node *np = iop->pathinfo.node_access; - - return rtems_deviceio_close( iop, np->major, np->minor ); -} diff --git a/cpukit/libfs/src/devfs/devfs_eval.c b/cpukit/libfs/src/devfs/devfs_eval.c deleted file mode 100644 index ba8e36fad0..0000000000 --- a/cpukit/libfs/src/devfs/devfs_eval.c +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file - * - * @brief Evaluate Patch - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -static devFS_node *devFS_search_node( - const devFS_data *data, - const char *path, - size_t pathlen, - devFS_node **free_node_ptr -) -{ - size_t i = 0; - size_t n = data->count; - devFS_node *nodes = data->nodes; - devFS_node *node = NULL; - devFS_node *free_node = NULL; - - for (i = 0; (free_node == NULL || node == NULL) && i < n; ++i) { - devFS_node *current = nodes + i; - - if (current->name != NULL) { - if ( - current->namelen == pathlen - && memcmp(current->name, path, pathlen) == 0 - ) { - node = current; - } - } else { - free_node = current; - } - } - - *free_node_ptr = free_node; - - return node; -} - -void devFS_eval_path( - rtems_filesystem_eval_path_context_t *ctx -) -{ - rtems_filesystem_location_info_t *currentloc = - rtems_filesystem_eval_path_get_currentloc(ctx); - devFS_node *free_node; - devFS_node *node = devFS_search_node( - devFS_get_data(currentloc), - rtems_filesystem_eval_path_get_path(ctx), - rtems_filesystem_eval_path_get_pathlen(ctx), - &free_node - ); - int eval_flags = rtems_filesystem_eval_path_get_flags(ctx); - - if (node != NULL) { - if ((eval_flags & RTEMS_FS_EXCLUSIVE) == 0) { - currentloc->node_access = node; - rtems_filesystem_eval_path_clear_path(ctx); - } else { - rtems_filesystem_eval_path_error(ctx, EEXIST); - } - } else { - if ((eval_flags & RTEMS_FS_MAKE) != 0) { - if (free_node != NULL) { - free_node->mode = S_IRWXU | S_IRWXG | S_IRWXO; - currentloc->node_access = free_node; - 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); - } else { - rtems_filesystem_eval_path_error(ctx, ENOSPC); - } - } else { - rtems_filesystem_eval_path_error(ctx, ENOENT); - } - } -} diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c deleted file mode 100644 index e8ad761f29..0000000000 --- a/cpukit/libfs/src/devfs/devfs_init.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file - * - * @brief Creates the Main Device Table - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -const rtems_filesystem_operations_table devFS_ops = { - .lock_h = rtems_filesystem_default_lock, - .unlock_h = rtems_filesystem_default_unlock, - .eval_path_h = devFS_eval_path, - .link_h = rtems_filesystem_default_link, - .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal, - .mknod_h = devFS_mknod, - .rmnod_h = rtems_filesystem_default_rmnod, - .fchmod_h = rtems_filesystem_default_fchmod, - .chown_h = rtems_filesystem_default_chown, - .clonenod_h = rtems_filesystem_default_clonenode, - .freenod_h = rtems_filesystem_default_freenode, - .mount_h = rtems_filesystem_default_mount, - .unmount_h = rtems_filesystem_default_unmount, - .fsunmount_me_h = rtems_filesystem_default_fsunmount, - .utime_h = rtems_filesystem_default_utime, - .symlink_h = rtems_filesystem_default_symlink, - .readlink_h = rtems_filesystem_default_readlink, - .rename_h = rtems_filesystem_default_rename, - .statvfs_h = rtems_filesystem_default_statvfs -}; - -const rtems_filesystem_file_handlers_r devFS_file_handlers = { - .open_h = devFS_open, - .close_h = devFS_close, - .read_h = devFS_read, - .write_h = devFS_write, - .ioctl_h = devFS_ioctl, - .lseek_h = rtems_filesystem_default_lseek_file, - .fstat_h = devFS_stat, - .ftruncate_h = rtems_filesystem_default_ftruncate, - .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, - .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, - .fcntl_h = rtems_filesystem_default_fcntl, - .kqfilter_h = rtems_filesystem_default_kqfilter, - .mmap_h = rtems_filesystem_default_mmap, - .poll_h = rtems_filesystem_default_poll, - .readv_h = rtems_filesystem_default_readv, - .writev_h = rtems_filesystem_default_writev -}; - -int devFS_initialize( - rtems_filesystem_mount_table_entry_t *mt_entry, - const void *data -) -{ - int rv = 0; - - if (data != NULL) { - mt_entry->ops = &devFS_ops; - mt_entry->immutable_fs_info = data; - mt_entry->mt_fs_root->location.handlers = &devFS_file_handlers; - } else { - errno = EINVAL; - rv = -1; - } - - return rv; -} - diff --git a/cpukit/libfs/src/devfs/devfs_mknod.c b/cpukit/libfs/src/devfs/devfs_mknod.c deleted file mode 100644 index 3b86d8c192..0000000000 --- a/cpukit/libfs/src/devfs/devfs_mknod.c +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file - * - * @brief Creates an item in the main device table. - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include -#include -#include - -#include - -int devFS_mknod( - const rtems_filesystem_location_info_t *parentloc, - const char *name, - size_t namelen, - mode_t mode, - dev_t dev -) -{ - int rv = 0; - - if (namelen != 3 || name [0] != 'd' || name [1] != 'e' || name [2] != 'v') { - if (S_ISBLK(mode) || S_ISCHR(mode)) { - char *dupname = malloc(namelen); - - if (dupname != NULL) { - devFS_node *node = parentloc->node_access; - - node->name = dupname; - node->namelen = namelen; - node->major = rtems_filesystem_dev_major_t(dev); - node->minor = rtems_filesystem_dev_minor_t(dev); - node->mode = mode; - memcpy(dupname, name, namelen); - } else { - errno = ENOMEM; - rv = -1; - } - } else { - errno = ENOTSUP; - rv = -1; - } - } else { - if (!S_ISDIR(mode)) { - errno = ENOTSUP; - rv = -1; - } - } - - return rv; -} diff --git a/cpukit/libfs/src/devfs/devfs_show.c b/cpukit/libfs/src/devfs/devfs_show.c deleted file mode 100644 index 07e67c6f51..0000000000 --- a/cpukit/libfs/src/devfs/devfs_show.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * - * @brief Retrieves and Prints all the Device Registered in System - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -void devFS_Show(void) -{ - rtems_filesystem_location_info_t *rootloc = &rtems_filesystem_root->location; - - if (rootloc->mt_entry->ops == &devFS_ops) { - const devFS_data *data = devFS_get_data(rootloc); - size_t i = 0; - size_t n = data->count; - devFS_node *nodes = data->nodes; - - for (i = 0; i < n; ++i) { - devFS_node *current = nodes + i; - - if (current->name != NULL) { - size_t j = 0; - size_t m = current->namelen; - - printk("/"); - for (j = 0; j < m; ++j) { - printk("%c", current->name [j]); - } - printk( - " %lu %lu\n", - (unsigned long) current->major, - (unsigned long) current->minor - ); - } - } - } -} diff --git a/cpukit/libfs/src/devfs/devioctl.c b/cpukit/libfs/src/devfs/devioctl.c deleted file mode 100644 index 693d30e825..0000000000 --- a/cpukit/libfs/src/devfs/devioctl.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file - * - * @brief Maps ioctl Operation to rtems_io_ioctl - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -int devFS_ioctl( - rtems_libio_t *iop, - ioctl_command_t command, - void *buffer -) -{ - const devFS_node *np = iop->pathinfo.node_access; - - return rtems_deviceio_control( iop, command, buffer, np->major, np->minor ); -} diff --git a/cpukit/libfs/src/devfs/devopen.c b/cpukit/libfs/src/devfs/devopen.c deleted file mode 100644 index d6d5c8062d..0000000000 --- a/cpukit/libfs/src/devfs/devopen.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file - * - * @brief Maps Open Operation to rtems_io_open - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -int devFS_open( - rtems_libio_t *iop, - const char *pathname, - int oflag, - mode_t mode -) -{ - const devFS_node *np = iop->pathinfo.node_access; - - return rtems_deviceio_open( - iop, - pathname, - oflag, - mode, - np->major, - np->minor - ); -} diff --git a/cpukit/libfs/src/devfs/devread.c b/cpukit/libfs/src/devfs/devread.c deleted file mode 100644 index 8ae3e84b65..0000000000 --- a/cpukit/libfs/src/devfs/devread.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file - * - * @brief DevFS Read - * @ingroup Read Operation to rtems_io_read - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -ssize_t devFS_read( - rtems_libio_t *iop, - void *buffer, - size_t count -) -{ - const devFS_node *np = iop->pathinfo.node_access; - - return rtems_deviceio_read( iop, buffer, count, np->major, np->minor ); -} diff --git a/cpukit/libfs/src/devfs/devstat.c b/cpukit/libfs/src/devfs/devstat.c deleted file mode 100644 index c88f729924..0000000000 --- a/cpukit/libfs/src/devfs/devstat.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file - * - * @brief Gets the Device File Information - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -int devFS_stat( - const rtems_filesystem_location_info_t *loc, - struct stat *buf -) -{ - int rv = 0; - const devFS_node *the_dev = loc->node_access; - - if (the_dev != NULL) { - buf->st_rdev = rtems_filesystem_make_dev_t( the_dev->major, the_dev->minor ); - buf->st_mode = the_dev->mode; - } else { - rv = rtems_filesystem_default_fstat(loc, buf); - } - - return rv; -} diff --git a/cpukit/libfs/src/devfs/devwrite.c b/cpukit/libfs/src/devfs/devwrite.c deleted file mode 100644 index 7fd8006776..0000000000 --- a/cpukit/libfs/src/devfs/devwrite.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file - * - * @brief Writes Operation to rtems_io_write - * @ingroup DevFsDeviceTable Define Device Table Type - */ - -/* - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -ssize_t devFS_write( - rtems_libio_t *iop, - const void *buffer, - size_t count -) -{ - const devFS_node *np = iop->pathinfo.node_access; - - return rtems_deviceio_write( iop, buffer, count, np->major, np->minor ); -} 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