File indexing completed on 2025-05-11 08:24:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <stdlib.h>
0043 #include <string.h>
0044
0045 #include <rtems/libio_.h>
0046
0047 RTEMS_CHAIN_DEFINE_EMPTY(rtems_filesystem_mount_table);
0048
0049 const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf = {
0050 5,
0051 128,
0052 7,
0053 255,
0054 255,
0055 1024,
0056 0,
0057 0 ,
0058 1,
0059 0,
0060 0,
0061 0
0062 };
0063
0064 static rtems_filesystem_mount_table_entry_t *alloc_mount_table_entry(
0065 const char *source_or_null,
0066 const char *target_or_null,
0067 const char *filesystemtype,
0068 size_t *target_length_ptr
0069 )
0070 {
0071 const char *target = target_or_null != NULL ? target_or_null : "/";
0072 size_t filesystemtype_size = strlen( filesystemtype ) + 1;
0073 size_t source_size = source_or_null != NULL ?
0074 strlen( source_or_null ) + 1 : 0;
0075 size_t target_size = strlen( target ) + 1;
0076 size_t size = sizeof( rtems_filesystem_mount_table_entry_t )
0077 + filesystemtype_size + source_size + target_size
0078 + sizeof( rtems_filesystem_global_location_t );
0079 rtems_filesystem_mount_table_entry_t *mt_entry = calloc( 1, size );
0080
0081 if ( mt_entry != NULL ) {
0082 rtems_filesystem_global_location_t *mt_fs_root =
0083 (rtems_filesystem_global_location_t *)
0084 ((char *) mt_entry + sizeof( *mt_entry ));
0085 char *str = (char *) mt_fs_root + sizeof( *mt_fs_root );
0086
0087 memcpy( str, filesystemtype, filesystemtype_size );
0088 mt_entry->type = str;
0089 str += filesystemtype_size;
0090
0091 if ( source_or_null != NULL ) {
0092 memcpy( str, source_or_null, source_size );
0093 mt_entry->dev = str;
0094 str += source_size;
0095 }
0096
0097 memcpy( str, target, target_size );
0098 mt_entry->target = str;
0099
0100 mt_entry->mounted = true;
0101 mt_entry->mt_fs_root = mt_fs_root;
0102 mt_entry->pathconf_limits_and_options = &rtems_filesystem_default_pathconf;
0103
0104 mt_fs_root->location.mt_entry = mt_entry;
0105 mt_fs_root->reference_count = 1;
0106
0107 rtems_chain_initialize(
0108 &mt_entry->location_chain,
0109 mt_fs_root,
0110 1,
0111 sizeof(*mt_fs_root)
0112 );
0113 }
0114
0115 *target_length_ptr = target_size - 1;
0116
0117 return mt_entry;
0118 }
0119
0120 static int register_subordinate_file_system(
0121 rtems_filesystem_mount_table_entry_t *mt_entry,
0122 const char *target
0123 )
0124 {
0125 int rv = 0;
0126 rtems_filesystem_eval_path_context_t ctx;
0127 int eval_flags = RTEMS_FS_PERMS_RWX
0128 | RTEMS_FS_FOLLOW_LINK;
0129 rtems_filesystem_location_info_t *currentloc =
0130 rtems_filesystem_eval_path_start( &ctx, target, eval_flags );
0131
0132 if ( !rtems_filesystem_location_is_instance_root( currentloc ) ) {
0133 rtems_filesystem_location_info_t targetloc;
0134 rtems_filesystem_global_location_t *mt_point_node;
0135
0136 rtems_filesystem_eval_path_extract_currentloc( &ctx, &targetloc );
0137 mt_point_node = rtems_filesystem_location_transform_to_global( &targetloc );
0138 mt_entry->mt_point_node = mt_point_node;
0139 rv = (*mt_point_node->location.mt_entry->ops->mount_h)( mt_entry );
0140 if ( rv == 0 ) {
0141 rtems_filesystem_mt_lock();
0142 rtems_chain_append_unprotected(
0143 &rtems_filesystem_mount_table,
0144 &mt_entry->mt_node
0145 );
0146 rtems_filesystem_mt_unlock();
0147 } else {
0148 rtems_filesystem_global_location_release( mt_point_node, true );
0149 }
0150 } else {
0151 rtems_filesystem_eval_path_error( &ctx, EBUSY );
0152 rv = -1;
0153 }
0154
0155 rtems_filesystem_eval_path_cleanup( &ctx );
0156
0157 return rv;
0158 }
0159
0160 static int register_root_file_system(
0161 rtems_filesystem_mount_table_entry_t *mt_entry
0162 )
0163 {
0164 int rv = 0;
0165
0166 rtems_filesystem_mt_lock();
0167 if ( rtems_chain_is_empty( &rtems_filesystem_mount_table ) ) {
0168 rtems_chain_append_unprotected(
0169 &rtems_filesystem_mount_table,
0170 &mt_entry->mt_node
0171 );
0172 } else {
0173 errno = EINVAL;
0174 rv = -1;
0175 }
0176 rtems_filesystem_mt_unlock();
0177
0178 if ( rv == 0 ) {
0179 rtems_filesystem_global_location_t *new_fs_root =
0180 rtems_filesystem_global_location_obtain( &mt_entry->mt_fs_root );
0181 rtems_filesystem_global_location_t *new_fs_current =
0182 rtems_filesystem_global_location_obtain( &mt_entry->mt_fs_root );
0183
0184 rtems_filesystem_global_location_assign(
0185 &rtems_filesystem_root,
0186 new_fs_root
0187 );
0188 rtems_filesystem_global_location_assign(
0189 &rtems_filesystem_current,
0190 new_fs_current
0191 );
0192 }
0193
0194 return rv;
0195 }
0196
0197 int mount(
0198 const char *source,
0199 const char *target,
0200 const char *filesystemtype,
0201 rtems_filesystem_options_t options,
0202 const void *data
0203 )
0204 {
0205 int rv = 0;
0206
0207 if (
0208 options == RTEMS_FILESYSTEM_READ_ONLY
0209 || options == RTEMS_FILESYSTEM_READ_WRITE
0210 ) {
0211 rtems_filesystem_fsmount_me_t fsmount_me_h =
0212 rtems_filesystem_get_mount_handler( filesystemtype );
0213
0214 if ( fsmount_me_h != NULL ) {
0215 size_t target_length = 0;
0216 rtems_filesystem_mount_table_entry_t *mt_entry = alloc_mount_table_entry(
0217 source,
0218 target,
0219 filesystemtype,
0220 &target_length
0221 );
0222
0223 if ( mt_entry != NULL ) {
0224 mt_entry->writeable = options == RTEMS_FILESYSTEM_READ_WRITE;
0225
0226 rv = (*fsmount_me_h)( mt_entry, data );
0227 if ( rv == 0 ) {
0228 if ( target != NULL ) {
0229 rv = register_subordinate_file_system( mt_entry, target );
0230 } else {
0231 rv = register_root_file_system( mt_entry );
0232 }
0233
0234 if ( rv != 0 ) {
0235 (*mt_entry->ops->fsunmount_me_h)( mt_entry );
0236 }
0237 }
0238
0239 if ( rv != 0 ) {
0240 free( mt_entry );
0241 }
0242 } else {
0243 errno = ENOMEM;
0244 rv = -1;
0245 }
0246 } else {
0247 errno = EINVAL;
0248 rv = -1;
0249 }
0250 } else {
0251 errno = EINVAL;
0252 rv = -1;
0253 }
0254
0255 return rv;
0256 }