source: rtems/cpukit/libcsupport/src/mount.c @ 8b65f38

4.11
Last change on this file since 8b65f38 was 8b65f38, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 7, 2012 at 3:12:49 PM

Filesystem: Rename function

Rename rtems_filesystem_location_is_root() into
rtems_filesystem_location_is_instance_root() to distinguish this from
the file system root directory of the current task environment.

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