source: rtems/cpukit/libcsupport/src/mount.c @ e02d5dd9

4.115
Last change on this file since e02d5dd9 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Mounts a File System
5 *  @ingroup FileSystemTypesAndMount
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2010.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  Copyright (c) 2010-2012 embedded brains GmbH.
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#if HAVE_CONFIG_H
20  #include "config.h"
21#endif
22
23#include <stdlib.h>
24#include <string.h>
25
26#include <rtems/libio_.h>
27
28RTEMS_CHAIN_DEFINE_EMPTY(rtems_filesystem_mount_table);
29
30const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf = {
31   5,    /* link_max: count */
32   128,  /* max_canon: max formatted input line size */
33   7,    /* max_input: max input line size */
34   255,  /* name_max: max name */
35   255,  /* path_max: max path */
36   1024, /* pipe_buf: pipe buffer size */
37   0,    /* posix_async_io: async IO supported on fs, 0=no, 1=yes */
38   0 ,   /* posix_chown_restrictions: can chown: 0=no, 1=yes */
39   1,    /* posix_no_trunc: error on filenames > max name, 0=no, 1=yes */
40   0,    /* posix_prio_io: priority IO, 0=no, 1=yes */
41   0,    /* posix_sync_io: file can be sync'ed, 0=no, 1=yes */
42   0     /* posix_vdisable: special char processing, 0=no, 1=yes */
43};
44
45static rtems_filesystem_mount_table_entry_t *alloc_mount_table_entry(
46  const char *source_or_null,
47  const char *target_or_null,
48  const char *filesystemtype,
49  size_t *target_length_ptr
50)
51{
52  const char *target = target_or_null != NULL ? target_or_null : "/";
53  size_t filesystemtype_size = strlen( filesystemtype ) + 1;
54  size_t source_size = source_or_null != NULL ?
55    strlen( source_or_null ) + 1 : 0;
56  size_t target_size = strlen( target ) + 1;
57  size_t size = sizeof( rtems_filesystem_mount_table_entry_t )
58    + filesystemtype_size + source_size + target_size
59    + sizeof( rtems_filesystem_global_location_t );
60  rtems_filesystem_mount_table_entry_t *mt_entry = calloc( 1, size );
61
62  if ( mt_entry != NULL ) {
63    rtems_filesystem_global_location_t *mt_fs_root =
64      (rtems_filesystem_global_location_t *)
65        ((char *) mt_entry + sizeof( *mt_entry ));
66    char *str = (char *) mt_fs_root + sizeof( *mt_fs_root );
67
68    memcpy( str, filesystemtype, filesystemtype_size );
69    mt_entry->type = str;
70    str += filesystemtype_size;
71
72    if ( source_or_null != NULL ) {
73      memcpy( str, source_or_null, source_size );
74      mt_entry->dev = str;
75      str += source_size;
76    }
77
78    memcpy( str, target, target_size );
79    mt_entry->target = str;
80    str += target_size;
81
82    mt_entry->mounted = true;
83    mt_entry->mt_fs_root = mt_fs_root;
84    mt_entry->pathconf_limits_and_options = &rtems_filesystem_default_pathconf;
85
86    mt_fs_root->location.mt_entry = mt_entry;
87    mt_fs_root->reference_count = 1;
88
89    rtems_chain_initialize(
90      &mt_entry->location_chain,
91      mt_fs_root,
92      1,
93      sizeof(*mt_fs_root)
94    );
95  }
96
97  *target_length_ptr = target_size - 1;
98
99  return mt_entry;
100}
101
102static int register_subordinate_file_system(
103  rtems_filesystem_mount_table_entry_t *mt_entry,
104  const char *target
105)
106{
107  int rv = 0;
108  rtems_filesystem_eval_path_context_t ctx;
109  int eval_flags = RTEMS_FS_PERMS_RWX
110    | RTEMS_FS_FOLLOW_LINK;
111  rtems_filesystem_location_info_t *currentloc =
112    rtems_filesystem_eval_path_start( &ctx, target, eval_flags );
113
114  if ( !rtems_filesystem_location_is_instance_root( currentloc ) ) {
115    rtems_filesystem_location_info_t targetloc;
116    rtems_filesystem_global_location_t *mt_point_node;
117
118    rtems_filesystem_eval_path_extract_currentloc( &ctx, &targetloc );
119    mt_point_node = rtems_filesystem_location_transform_to_global( &targetloc );
120    mt_entry->mt_point_node = mt_point_node;
121    rv = (*mt_point_node->location.mt_entry->ops->mount_h)( mt_entry );
122    if ( rv == 0 ) {
123      rtems_filesystem_mt_lock();
124      rtems_chain_append_unprotected(
125        &rtems_filesystem_mount_table,
126        &mt_entry->mt_node
127      );
128      rtems_filesystem_mt_unlock();
129    } else {
130      rtems_filesystem_global_location_release( mt_point_node );
131    }
132  } else {
133    rtems_filesystem_eval_path_error( &ctx, EBUSY );
134    rv = -1;
135  }
136
137  rtems_filesystem_eval_path_cleanup( &ctx );
138
139  return rv;
140}
141
142static int register_root_file_system(
143  rtems_filesystem_mount_table_entry_t *mt_entry
144)
145{
146  int rv = 0;
147
148  rtems_filesystem_mt_lock();
149  if ( rtems_chain_is_empty( &rtems_filesystem_mount_table ) ) {
150    rtems_chain_append_unprotected(
151      &rtems_filesystem_mount_table,
152      &mt_entry->mt_node
153    );
154  } else {
155    errno = EINVAL;
156    rv = -1;
157  }
158  rtems_filesystem_mt_unlock();
159
160  if ( rv == 0 ) {
161    rtems_filesystem_global_location_t *new_fs_root =
162      rtems_filesystem_global_location_obtain( &mt_entry->mt_fs_root );
163    rtems_filesystem_global_location_t *new_fs_current =
164      rtems_filesystem_global_location_obtain( &mt_entry->mt_fs_root );
165
166    rtems_filesystem_global_location_assign(
167      &rtems_filesystem_root,
168      new_fs_root
169    );
170    rtems_filesystem_global_location_assign(
171      &rtems_filesystem_current,
172      new_fs_current
173    );
174  }
175
176  return rv;
177}
178
179int mount(
180  const char                 *source,
181  const char                 *target,
182  const char                 *filesystemtype,
183  rtems_filesystem_options_t options,
184  const void                 *data
185)
186{
187  int rv = 0;
188
189  if (
190    options == RTEMS_FILESYSTEM_READ_ONLY
191      || options == RTEMS_FILESYSTEM_READ_WRITE
192  ) {
193    rtems_filesystem_fsmount_me_t fsmount_me_h =
194      rtems_filesystem_get_mount_handler( filesystemtype );
195
196    if ( fsmount_me_h != NULL ) {
197      size_t target_length = 0;
198      rtems_filesystem_mount_table_entry_t *mt_entry = alloc_mount_table_entry(
199        source,
200        target,
201        filesystemtype,
202        &target_length
203      );
204
205      if ( mt_entry != NULL ) {
206        mt_entry->writeable = options == RTEMS_FILESYSTEM_READ_WRITE;
207
208        rv = (*fsmount_me_h)( mt_entry, data );
209        if ( rv == 0 ) {
210          if ( target != NULL ) {
211            rv = register_subordinate_file_system( mt_entry, target );
212          } else {
213            rv = register_root_file_system( mt_entry );
214          }
215
216          if ( rv != 0 ) {
217            (*mt_entry->ops->fsunmount_me_h)( mt_entry );
218          }
219        }
220
221        if ( rv != 0 ) {
222          free( mt_entry );
223        }
224      } else {
225        errno = ENOMEM;
226        rv = -1;
227      }
228    } else {
229      errno = EINVAL;
230      rv = -1;
231    }
232  } else {
233    errno = EINVAL;
234    rv = -1;
235  }
236
237  return rv;
238}
Note: See TracBrowser for help on using the repository browser.