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

4.11
Last change on this file since da154e14 was da154e14, checked in by Sebastian Huber <sebastian.huber@…>, on May 14, 2012 at 2:55:41 PM

Filesystem: Move operations to mount table entry

The scope of the file system operations is the file system instance.
The scope of the file system node handlers is the file location. The
benefit of moving the operations to the mount table entry is a size
reduction of the file location (rtems_filesystem_location_info_t). The
code size is slightly increased due to additional load instructions.

Restructure rtems_filesystem_mount_table_entry_t to improve cache
efficiency.

  • Property mode set to 100644
File size: 6.4 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_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.