Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:15

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  @brief Mounts a File System
0007  *  @ingroup FileSystemTypesAndMount
0008  */
0009 
0010 /*
0011  *  COPYRIGHT (c) 1989-2010.
0012  *  On-Line Applications Research Corporation (OAR).
0013  *
0014  *  Copyright (C) 2010, 2012 embedded brains GmbH & Co. KG
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
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,    /* link_max: count */
0051    128,  /* max_canon: max formatted input line size */
0052    7,    /* max_input: max input line size */
0053    255,  /* name_max: max name */
0054    255,  /* path_max: max path */
0055    1024, /* pipe_buf: pipe buffer size */
0056    0,    /* posix_async_io: async IO supported on fs, 0=no, 1=yes */
0057    0 ,   /* posix_chown_restrictions: can chown: 0=no, 1=yes */
0058    1,    /* posix_no_trunc: error on filenames > max name, 0=no, 1=yes */
0059    0,    /* posix_prio_io: priority IO, 0=no, 1=yes */
0060    0,    /* posix_sync_io: file can be sync'ed, 0=no, 1=yes */
0061    0     /* posix_vdisable: special char processing, 0=no, 1=yes */
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 }