source: rtems/cpukit/libcsupport/src/mount.c @ 50f32b11

4.104.114.84.95
Last change on this file since 50f32b11 was 50f32b11, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/18/04 at 06:05:35

Remove stray white spaces.

  • Property mode set to 100644
File size: 6.8 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-1999.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 *
17 *  $Id$
18 */
19
20#if HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <rtems/chain.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <errno.h>
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33
34#include <rtems/libio_.h>
35
36Chain_Control rtems_filesystem_mount_table_control;
37
38/*
39 *  Prototypes that probably should be somewhere else.
40 */
41
42int init_fs_mount_table( void );
43static int Is_node_fs_root(
44  rtems_filesystem_location_info_t  *loc
45);
46
47
48/*
49 *  XXX
50 */
51
52#define FOUND      0
53#define NOT_FOUND -1
54
55/*
56 *  mount
57 *
58 *  This routine will attempt to mount a new file system at the specified
59 *  mount point. A series of tests will be run to determine if any of the
60 *  following reasons exist to prevent the mount operation:
61 *
62 *      1) The file system type or options are not valid
63 *      2) No new file system root node is specified
64 *      3) The selected file system has already been mounted
65 *      4) The mount point exists with the proper permissions to allow mounting
66 *      5) The selected mount point already has a file system mounted to it
67 *
68 */
69
70int mount(
71  rtems_filesystem_mount_table_entry_t **mt_entry,
72  rtems_filesystem_operations_table    *fs_ops,
73  rtems_filesystem_options_t            options,
74  char                                 *device,
75  char                                 *mount_point
76)
77{
78  rtems_filesystem_location_info_t      loc;
79  rtems_filesystem_mount_table_entry_t *temp_mt_entry = NULL;
80  rtems_filesystem_location_info_t     *loc_to_free = NULL;
81  size_t size;
82
83/* XXX add code to check for required operations */
84
85  /*
86   *  Is there a file system operations table?
87   */
88
89  if ( fs_ops == NULL ) {
90    errno = EINVAL;
91    return -1;
92  }
93
94  /*
95   *  Are the file system options valid?
96   */
97
98  if ( options != RTEMS_FILESYSTEM_READ_ONLY &&
99       options != RTEMS_FILESYSTEM_READ_WRITE ) {
100    errno = EINVAL;
101    return -1;
102  }
103
104  /* Do they support being mounted at all ? */
105  if ( !fs_ops->fsmount_me_h ) {
106    errno = ENOTSUP;
107    goto cleanup_and_bail;
108  }
109
110
111  /*
112   * Allocate a mount table entry
113   */
114
115   size = sizeof(rtems_filesystem_mount_table_entry_t);
116   if ( device )
117     size += strlen( device ) + 1;
118   temp_mt_entry = malloc( size );
119
120   if ( !temp_mt_entry ) {
121     errno = ENOMEM;
122     return -1;
123   }
124
125   temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry;
126   temp_mt_entry->options = options;
127   if ( device ) {
128     temp_mt_entry->dev =
129       (char *)temp_mt_entry + sizeof( rtems_filesystem_mount_table_entry_t );
130     strcpy( temp_mt_entry->dev, device );
131   } else
132     temp_mt_entry->dev = 0;
133
134  /*
135   *  The mount_point should be a directory with read/write/execute
136   *  permissions in the existing tree.
137   */
138
139  if ( mount_point ) {
140
141    if ( rtems_filesystem_evaluate_path(
142            mount_point, RTEMS_LIBIO_PERMS_RWX, &loc, TRUE ) == -1 )
143      goto cleanup_and_bail;
144
145    loc_to_free = &loc;
146
147    /*
148     * Test for node_type_h
149     */
150
151    if (!loc.ops->node_type_h) {
152      errno =  ENOTSUP;
153      goto cleanup_and_bail;
154    }
155
156    /*
157     *  Test to see if it is a directory
158     */
159
160    if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
161      errno = ENOTDIR;
162      goto cleanup_and_bail;
163    }
164
165    /*
166     *  You can only mount one file system onto a single mount point.
167     */
168
169    if ( Is_node_fs_root(  &loc ) ){
170      errno = EBUSY;
171      goto cleanup_and_bail;
172    }
173
174    /*
175     *  This must be a good mount point, so move the location information
176     *  into the allocated mount entry.  Note:  the information that
177     *  may have been allocated in loc should not be sent to freenode
178     *  until the system is unmounted.  It may be needed to correctly
179     *  traverse the tree.
180     */
181
182    temp_mt_entry->mt_point_node.node_access = loc.node_access;
183    temp_mt_entry->mt_point_node.handlers = loc.handlers;
184    temp_mt_entry->mt_point_node.ops = loc.ops;
185    temp_mt_entry->mt_point_node.mt_entry = loc.mt_entry;
186
187    /*
188     *  This link to the parent is only done when we are dealing with system
189     *  below the base file system
190     */
191
192    if ( !loc.ops->mount_h ){
193      errno = ENOTSUP;
194      goto cleanup_and_bail;
195    }
196
197    if ( loc.ops->mount_h( temp_mt_entry ) ) {
198      goto cleanup_and_bail;
199    }
200  } else {
201
202    /*
203     *  This is a mount of the base file system --> The
204     *  mt_point_node.node_access will be set to null to indicate that this
205     *  is the root of the entire file system.
206     */
207
208    temp_mt_entry->mt_fs_root.node_access = NULL;
209    temp_mt_entry->mt_fs_root.handlers = NULL;
210    temp_mt_entry->mt_fs_root.ops = NULL;
211
212    temp_mt_entry->mt_point_node.node_access = NULL;
213    temp_mt_entry->mt_point_node.handlers = NULL;
214    temp_mt_entry->mt_point_node.ops = NULL;
215    temp_mt_entry->mt_point_node.mt_entry = NULL;
216  }
217
218  if ( fs_ops->fsmount_me_h( temp_mt_entry ) ) {
219        /* try to undo the mount operation */
220        if ( loc.ops->unmount_h ) {
221                loc.ops->unmount_h( temp_mt_entry );
222    }
223    goto cleanup_and_bail;
224  }
225
226  /*
227   *  Add the mount table entry to the mount table chain
228   */
229
230  Chain_Append( &rtems_filesystem_mount_table_control, &temp_mt_entry->Node );
231
232  *mt_entry = temp_mt_entry;
233
234  return 0;
235
236cleanup_and_bail:
237
238  free( temp_mt_entry );
239
240  if ( loc_to_free )
241    rtems_filesystem_freenode( loc_to_free );
242
243  return -1;
244}
245
246
247
248/*
249 *  init_fs_mount_table
250 *
251 *  This routine will initialize the chain control element that manages the
252 *  mount table chain.
253 */
254
255int init_fs_mount_table()
256{
257  Chain_Initialize_empty ( &rtems_filesystem_mount_table_control );
258  return 0;
259}
260
261/*
262 *  Is_node_fs_root
263 *
264 *  This routine will run through the entries that currently exist in the
265 *  mount table chain. For each entry in the mount table chain it will
266 *  compare the mount tables root node to the node describing the selected
267 *  mount point. If any match is found true is returned else false is
268 *  returned.
269 *
270 */
271
272static int Is_node_fs_root(
273  rtems_filesystem_location_info_t  *loc
274)
275{
276  Chain_Node                           *the_node;
277  rtems_filesystem_mount_table_entry_t *the_mount_entry;
278
279  /*
280   * For each mount table entry
281   */
282
283  for ( the_node = rtems_filesystem_mount_table_control.first;
284        !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
285        the_node = the_node->next ) {
286     the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
287     if ( the_mount_entry->mt_fs_root.node_access  == loc->node_access )
288        return TRUE;
289  }
290  return FALSE;
291}
Note: See TracBrowser for help on using the repository browser.