From 7d01d244d7484056f8c0c101eb500fe8cfcfd9bb Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 7 Jun 2010 15:35:24 +0000 Subject: 2010-06-07 Sebastian Huber * libcsupport/include/rtems/libio_.h: Declare rtems_filesystem_mount_table_control. * libcsupport/include/rtems/libio.h: Removed rtems_filesystem_table_first(), rtems_filesystem_table_next() and rtems_filesystem_table_node_t declarations. Declare rtems_per_filesystem_routine, rtems_filesystem_iterate() and rtems_filesystem_get_mount_handler(). * libcsupport/src/mount.c: Added rtems_filesystem_mounts_first() and rtems_filesystem_mounts_next(). Simplify mount(). Removed rtems_filesystem_mount_table_control_init. Use rtems_filesystem_get_mount_handler(). * libcsupport/src/mount-mgr.c: Removed rtems_filesystem_mounts_first() and rtems_filesystem_mounts_next(). Added rtems_filesystem_iterate() and rtems_filesystem_get_mount_handler(). Use rtems_libio_lock() and rtems_libio_unlock(); * sapi/include/confdefs.h, libmisc/shell/main_mount.c: Update for mount API changes. --- cpukit/libcsupport/include/rtems/libio.h | 49 +++++-- cpukit/libcsupport/include/rtems/libio_.h | 5 + cpukit/libcsupport/src/mount-mgr.c | 217 +++++++++++++--------------- cpukit/libcsupport/src/mount.c | 230 ++++++++++++++---------------- 4 files changed, 246 insertions(+), 255 deletions(-) (limited to 'cpukit/libcsupport') diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h index dadc446ead..da9fa884a0 100644 --- a/cpukit/libcsupport/include/rtems/libio.h +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -289,32 +289,51 @@ struct _rtems_filesystem_operations_table { rtems_filesystem_statvfs_t statvfs_h; }; -/* - * File system table used by mount to manage file systems. +/** + * @brief File system table entry. */ typedef struct rtems_filesystem_table_t { const char *type; rtems_filesystem_fsmount_me_t mount_h; } rtems_filesystem_table_t; -/* - * File system table runtime loaded nodes. +/** + * @brief Static table of file systems. + * + * Externally defined by confdefs.h or the user. */ -typedef struct rtems_filesystem_table_node_t { - rtems_chain_node node; - rtems_filesystem_table_t entry; -} rtems_filesystem_table_node_t; +extern const rtems_filesystem_table_t rtems_filesystem_table []; -/* - * Get the first entry in the filesystem table. +/** + * @brief Per file system table entry routine type. + * + * Return @c true to continue the iteration, and @c false to stop. */ -const rtems_filesystem_table_t* rtems_filesystem_table_first( void ); +typedef bool (*rtems_per_filesystem_routine)( + const rtems_filesystem_table_t *entry, + void *arg +); -/* - * Get the next entry in the file system table. +/** + * @brief Iterates over the file system table. + * + * For each file system table entry the @a routine will be called with the + * table entry and the @a routine_arg parameter. */ -const rtems_filesystem_table_t* -rtems_filesystem_table_next( const rtems_filesystem_table_t *entry ); +void +rtems_filesystem_iterate( + rtems_per_filesystem_routine routine, + void *routine_arg +); + +/** + * @brief Returns the file system mount handler associated with the @a type, or + * @c NULL if no such association exists. + */ +rtems_filesystem_fsmount_me_t +rtems_filesystem_get_mount_handler( + const char *type +); /* * Get the first entry in the mount table. diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h index ad00f8785f..3f897885bb 100644 --- a/cpukit/libcsupport/include/rtems/libio_.h +++ b/cpukit/libcsupport/include/rtems/libio_.h @@ -39,6 +39,11 @@ extern "C" { extern rtems_id rtems_libio_semaphore; extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers; +/* + * Mount table list. + */ +extern rtems_chain_control rtems_filesystem_mount_table_control; + /* * File descriptor Table Information */ diff --git a/cpukit/libcsupport/src/mount-mgr.c b/cpukit/libcsupport/src/mount-mgr.c index 68180a699d..03ead45c9b 100644 --- a/cpukit/libcsupport/src/mount-mgr.c +++ b/cpukit/libcsupport/src/mount-mgr.c @@ -6,6 +6,8 @@ * * COPYRIGHT (c) Chris Johns 2010. * + * Copyright (c) 2010 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -30,158 +32,139 @@ #include -/* - * External defined by confdefs.h or the user. - */ -extern const rtems_filesystem_table_t configuration_filesystem_table[]; - -/* - * Points to a list of filesystems added at runtime. - */ -extern rtems_chain_control *rtems_filesystem_table; +typedef struct { + rtems_chain_node node; + rtems_filesystem_table_t entry; +} filesystem_node; -/* - * Mount table list. - */ -extern rtems_chain_control rtems_filesystem_mount_table_control; -extern bool rtems_filesystem_mount_table_control_init; +RTEMS_CHAIN_DEFINE_EMPTY(filesystem_chain); -/* - * Get the first entry in the filesystem table. - */ -const rtems_filesystem_table_t* -rtems_filesystem_table_first( - void +void +rtems_filesystem_iterate( + rtems_per_filesystem_routine routine, + void *routine_arg ) { - /* - * We can assume this because it is the root file system. - */ - return &configuration_filesystem_table[0]; -} + const rtems_filesystem_table_t *table_entry = &rtems_filesystem_table [0]; + rtems_chain_node *node = NULL; -/* - * Get the next entry in the file system table. - */ -const rtems_filesystem_table_t* -rtems_filesystem_table_next( - const rtems_filesystem_table_t *entry -) -{ - const rtems_filesystem_table_t* fs; - - fs = rtems_filesystem_table_first( ); - - while ( fs->type && ( fs != entry ) ) - ++fs; - - if ( fs->type ) { - ++fs; - if ( fs->type ) - return fs; + while ( table_entry->type ) { + if ( !(*routine)( table_entry, routine_arg ) ) { + break; + } + + ++table_entry; } - if ( rtems_filesystem_table ) { - rtems_chain_node* node; - for (node = rtems_chain_first( rtems_filesystem_table ); - !rtems_chain_is_tail( rtems_filesystem_table, node); - node = rtems_chain_next( node )) { - rtems_filesystem_table_node_t* tnode; - tnode = (rtems_filesystem_table_node_t*) node; - if ( entry == &tnode->entry ) { - node = rtems_chain_next( node ); - if ( !rtems_chain_is_tail( rtems_filesystem_table, node ) ) { - tnode = (rtems_filesystem_table_node_t*) node; - return &tnode->entry; - } - } + rtems_libio_lock(); + for ( + node = rtems_chain_first( &filesystem_chain ); + !rtems_chain_is_tail( &filesystem_chain, node ); + node = rtems_chain_next( node ) + ) { + const filesystem_node *fsn = (filesystem_node *) node; + + if ( !(*routine)( &fsn->entry, routine_arg ) ) { + break; } } - - return NULL; + rtems_libio_unlock(); } -/* - * Get the first entry in the mount table. - */ -rtems_filesystem_mount_table_entry_t* -rtems_filesystem_mounts_first( - void -) +typedef struct { + const char *type; + rtems_filesystem_fsmount_me_t mount_h; +} find_arg; + +static bool find_handler(const rtems_filesystem_table_t *entry, void *arg) { - rtems_filesystem_mount_table_entry_t* entry = NULL; - if ( rtems_filesystem_mount_table_control_init ) { - if ( !rtems_chain_is_empty( &rtems_filesystem_mount_table_control ) ) - entry = (rtems_filesystem_mount_table_entry_t*) - rtems_chain_first( &rtems_filesystem_mount_table_control ); + find_arg *fa = arg; + + if ( strcmp( entry->type, fa->type ) != 0 ) { + return true; + } else { + fa->mount_h = entry->mount_h; + + return true; } - return entry; } -/* - * Get the next entry in the mount table. - */ -rtems_filesystem_mount_table_entry_t* -rtems_filesystem_mounts_next( - rtems_filesystem_mount_table_entry_t *entry +rtems_filesystem_fsmount_me_t +rtems_filesystem_get_mount_handler( + const char *type ) { - if ( !rtems_filesystem_mount_table_control_init || !entry ) - return NULL; - return (rtems_filesystem_mount_table_entry_t*) rtems_chain_next( &entry->Node ); + find_arg fa = { + .type = type, + .mount_h = NULL + }; + + if ( type != NULL ) { + rtems_filesystem_iterate( find_handler, &fa ); + } + + return fa.mount_h; } -/* - * Register a file system. - */ int rtems_filesystem_register( const char *type, rtems_filesystem_fsmount_me_t mount_h ) { - rtems_filesystem_table_node_t *fs; - if ( !rtems_filesystem_table ) { - rtems_filesystem_table = malloc( sizeof( rtems_chain_control ) ); - if ( !rtems_filesystem_table ) - rtems_set_errno_and_return_minus_one( ENOMEM ); - rtems_chain_initialize_empty ( rtems_filesystem_table ); - } - fs = malloc( sizeof( rtems_filesystem_table_node_t ) ); - if ( !fs ) - rtems_set_errno_and_return_minus_one( ENOMEM ); - fs->entry.type = strdup( type ); - if ( !fs->entry.type ) { - free( fs ); + size_t fsn_size = sizeof( filesystem_node ) + strlen(type) + 1; + filesystem_node *fsn = malloc( fsn_size ); + char *type_storage = (char *) fsn + sizeof( filesystem_node ); + + if ( fsn == NULL ) rtems_set_errno_and_return_minus_one( ENOMEM ); - } - fs->entry.mount_h = mount_h; - rtems_chain_append( rtems_filesystem_table, &fs->node ); + + strcpy(type_storage, type); + fsn->entry.type = type_storage; + fsn->entry.mount_h = mount_h; + + rtems_libio_lock(); + if ( rtems_filesystem_get_mount_handler( type ) == NULL ) { + rtems_chain_append( &filesystem_chain, &fsn->node ); + } else { + rtems_libio_unlock(); + free( fsn ); + + rtems_set_errno_and_return_minus_one( EINVAL ); + } + rtems_libio_unlock(); + return 0; } -/* - * Unregister a file system. - */ int rtems_filesystem_unregister( const char *type ) { - if ( rtems_filesystem_table ) { - rtems_chain_node *node; - for (node = rtems_chain_first( rtems_filesystem_table ); - !rtems_chain_is_tail( rtems_filesystem_table, node ); - node = rtems_chain_next( node ) ) { - rtems_filesystem_table_node_t *fs; - fs = (rtems_filesystem_table_node_t*) node; - if ( strcmp( fs->entry.type, type ) == 0 ) { - rtems_chain_extract( node ); - free( (void*) fs->entry.type ); - free( fs ); - return 0; - } + rtems_chain_node *node = NULL; + + if ( type == NULL ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + rtems_libio_lock(); + for ( + node = rtems_chain_first( &filesystem_chain ); + !rtems_chain_is_tail( &filesystem_chain, node ); + node = rtems_chain_next( node ) + ) { + filesystem_node *fsn = (filesystem_node *) node; + + if ( strcmp( fsn->entry.type, type ) == 0 ) { + rtems_chain_extract( node ); + free( fsn ); + rtems_libio_unlock(); + + return 0; } } + rtems_libio_unlock(); + rtems_set_errno_and_return_minus_one( ENOENT ); } diff --git a/cpukit/libcsupport/src/mount.c b/cpukit/libcsupport/src/mount.c index 3e3c47166d..07f41f2ee4 100644 --- a/cpukit/libcsupport/src/mount.c +++ b/cpukit/libcsupport/src/mount.c @@ -10,6 +10,8 @@ * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2010 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -24,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -33,21 +36,10 @@ #include -/* - * External defined by confdefs.h or the user. - */ -extern const rtems_filesystem_table_t configuration_filesystem_table[]; - -/* - * Points to a list of filesystems added at runtime. - */ -rtems_chain_control *rtems_filesystem_table; - /* * Mount table list. */ -rtems_chain_control rtems_filesystem_mount_table_control; -bool rtems_filesystem_mount_table_control_init; +RTEMS_CHAIN_DEFINE_EMPTY(rtems_filesystem_mount_table_control); /* * Default pathconfs. @@ -79,27 +71,64 @@ const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf = */ static bool Is_node_fs_root( - rtems_filesystem_location_info_t *loc + rtems_filesystem_location_info_t *loc ) { - rtems_chain_node *the_node; - rtems_filesystem_mount_table_entry_t *the_mount_entry; + rtems_chain_node *node = NULL; /* * For each mount table entry */ - if ( rtems_filesystem_mount_table_control_init ) { - for ( the_node = rtems_chain_first( &rtems_filesystem_mount_table_control ); - !rtems_chain_is_tail( &rtems_filesystem_mount_table_control, the_node ); - the_node = rtems_chain_next( the_node ) ) { - the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node; - if ( the_mount_entry->mt_fs_root.node_access == loc->node_access ) - return true; - } + for ( node = rtems_chain_first( &rtems_filesystem_mount_table_control ); + !rtems_chain_is_tail( &rtems_filesystem_mount_table_control, node ); + node = rtems_chain_next( node ) ) { + rtems_filesystem_mount_table_entry_t *mount_table_entry = + (rtems_filesystem_mount_table_entry_t *) node; + + if ( mount_table_entry->mt_fs_root.node_access == loc->node_access ) + return true; } + return false; } +static rtems_filesystem_mount_table_entry_t *alloc_mount_table_entry( + const char *source, + const char *target, + const char *filesystemtype, + size_t *target_length_ptr +) +{ + const char *target_str = target ? target : "/"; + size_t filesystemtype_size = strlen( filesystemtype ) + 1; + size_t source_size = source ? strlen( source ) + 1 : 0; + size_t target_length = strlen( target_str ); + size_t size = sizeof( rtems_filesystem_mount_table_entry_t ) + + filesystemtype_size + source_size + target_length + 1; + rtems_filesystem_mount_table_entry_t *mt_entry = calloc( 1, size ); + + if ( mt_entry ) { + char *str = (char *) mt_entry + sizeof( *mt_entry ); + + mt_entry->type = str; + strcpy( str, filesystemtype ); + + if ( source ) { + str += filesystemtype_size; + mt_entry->dev = str; + strcpy( str, source ); + } + + str += source_size; + mt_entry->target = str; + strcpy( str, target ); + } + + *target_length_ptr = target_length; + + return mt_entry; +} + /* * mount * @@ -121,114 +150,54 @@ int mount( const char *filesystemtype, rtems_filesystem_options_t options, const void *data - ) +) { - const rtems_filesystem_table_t *entry; + rtems_filesystem_fsmount_me_t mount_h = NULL; rtems_filesystem_location_info_t loc; rtems_filesystem_mount_table_entry_t *mt_entry = NULL; rtems_filesystem_location_info_t *loc_to_free = NULL; - size_t size; - - /* - * If mount is ever called we allocate the mount table control structure. - */ - if ( !rtems_filesystem_mount_table_control_init ) { - rtems_filesystem_mount_table_control_init = true; - rtems_chain_initialize_empty ( &rtems_filesystem_mount_table_control ); - } + bool has_target = target != NULL; + size_t target_length = 0; /* * Are the file system options valid? */ if ( options != RTEMS_FILESYSTEM_READ_ONLY && - options != RTEMS_FILESYSTEM_READ_WRITE ) { - errno = EINVAL; - return -1; - } - - /* - * Check the type. - */ - if (!filesystemtype) { - errno = EINVAL; - return -1; - } + options != RTEMS_FILESYSTEM_READ_WRITE ) + rtems_set_errno_and_return_minus_one( EINVAL ); - if (strlen(filesystemtype) >= 128) { - errno = EINVAL; - return -1; - } - /* - * Check the configuration table filesystems then check any runtime added - * file systems. + * Get mount handler */ - entry = &configuration_filesystem_table[0]; - while (entry->type) { - if (strcmp (filesystemtype, entry->type) == 0) - break; - ++entry; - } - - if (!entry->type) { - entry = NULL; - if (rtems_filesystem_table) { - rtems_chain_node *the_node; - for (the_node = rtems_chain_first(rtems_filesystem_table); - !rtems_chain_is_tail(rtems_filesystem_table, the_node); - the_node = rtems_chain_next(the_node)) { - entry = &(((rtems_filesystem_table_node_t*) the_node)->entry); - if (strcmp (filesystemtype, entry->type) == 0) - break; - entry = NULL; - } - } - } + mount_h = rtems_filesystem_get_mount_handler( filesystemtype ); + if ( !mount_h ) + rtems_set_errno_and_return_minus_one( EINVAL ); - if (!entry) - { - errno = EINVAL; - return -1; - } - /* * Allocate a mount table entry */ + mt_entry = alloc_mount_table_entry( + source, + target, + filesystemtype, + &target_length + ); + if ( !mt_entry ) + rtems_set_errno_and_return_minus_one( ENOMEM ); - size = sizeof(rtems_filesystem_mount_table_entry_t); - if ( source ) - size += strlen( source ) + 1; - - mt_entry = malloc( size ); - if ( !mt_entry ) { - errno = ENOMEM; - return -1; - } - - memset( mt_entry, 0, size ); - mt_entry->mt_fs_root.mt_entry = mt_entry; - mt_entry->type = entry->type; mt_entry->options = options; mt_entry->pathconf_limits_and_options = rtems_filesystem_default_pathconf; - - if ( source ) { - mt_entry->dev = - (char *)mt_entry + sizeof( rtems_filesystem_mount_table_entry_t ); - strcpy( mt_entry->dev, source ); - } else - mt_entry->dev = 0; /* * The mount_point should be a directory with read/write/execute * permissions in the existing tree. */ - if ( target ) { - + if ( has_target ) { if ( rtems_filesystem_evaluate_path( - target, strlen( target ), RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) + target, target_length, RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) goto cleanup_and_bail; loc_to_free = &loc; @@ -272,7 +241,7 @@ int mount( mt_entry->mt_point_node.handlers = loc.handlers; mt_entry->mt_point_node.ops = loc.ops; mt_entry->mt_point_node.mt_entry = loc.mt_entry; - + /* * This link to the parent is only done when we are dealing with system * below the base file system @@ -286,10 +255,7 @@ int mount( if ( loc.ops->mount_h( mt_entry ) ) { goto cleanup_and_bail; } - - mt_entry->target = strdup( target ); } else { - /* * Do we already have a base file system ? */ @@ -297,26 +263,15 @@ int mount( errno = EINVAL; goto cleanup_and_bail; } - + /* * This is a mount of the base file system --> The - * mt_point_node.node_access will be set to null to indicate that this + * mt_point_node.node_access will be left to null to indicate that this * is the root of the entire file system. */ - - mt_entry->mt_fs_root.node_access = NULL; - mt_entry->mt_fs_root.handlers = NULL; - mt_entry->mt_fs_root.ops = NULL; - - mt_entry->mt_point_node.node_access = NULL; - mt_entry->mt_point_node.handlers = NULL; - mt_entry->mt_point_node.ops = NULL; - mt_entry->mt_point_node.mt_entry = NULL; - - mt_entry->target = "/"; } - if ( entry->mount_h( mt_entry, data ) ) { + if ( (*mount_h)( mt_entry, data ) ) { /* * Try to undo the mount operation */ @@ -332,14 +287,13 @@ int mount( rtems_chain_append( &rtems_filesystem_mount_table_control, &mt_entry->Node ); - if ( !target ) + if ( !has_target ) rtems_filesystem_root = mt_entry->mt_fs_root; return 0; cleanup_and_bail: - free( (void*) mt_entry->target ); free( mt_entry ); if ( loc_to_free ) @@ -348,3 +302,33 @@ cleanup_and_bail: return -1; } +/* + * Get the first entry in the mount table. + */ +rtems_filesystem_mount_table_entry_t * +rtems_filesystem_mounts_first( + void +) +{ + rtems_filesystem_mount_table_entry_t *entry = NULL; + + if ( !rtems_chain_is_empty( &rtems_filesystem_mount_table_control ) ) + entry = (rtems_filesystem_mount_table_entry_t *) + rtems_chain_first( &rtems_filesystem_mount_table_control ); + + return entry; +} + +/* + * Get the next entry in the mount table. + */ +rtems_filesystem_mount_table_entry_t * +rtems_filesystem_mounts_next( + rtems_filesystem_mount_table_entry_t *entry +) +{ + if ( !entry ) + return NULL; + return (rtems_filesystem_mount_table_entry_t *) + rtems_chain_next( &entry->Node ); +} -- cgit v1.2.3