source: rtems/c/src/lib/libc/mount.c @ df25c998

4.104.114.84.95
Last change on this file since df25c998 was 9c49db4, checked in by Joel Sherrill <joel.sherrill@…>, on 01/08/01 at 18:26:44

2001-01-08 Ralf Corsepius <corsepiu@…>

  • configure.in: Add libc/config.h
  • libc/Makefile.am: Add INCLUDES += -I. to pickup config.h
  • libc/.cvsignore: Add config.h and stamp-h
  • libc/*.c: Add config.h support.
  • 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-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.OARcorp.com/rtems/license.html.
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 <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;
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  /*
105   * Allocate a mount table entry
106   */
107
108   size = sizeof(rtems_filesystem_mount_table_entry_t);
109   if ( device )
110     size += strlen( device ) + 1;
111   temp_mt_entry = malloc( size );
112
113   if ( !temp_mt_entry ) {
114     errno = ENOMEM;
115     return -1;
116   }
117
118   temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry;
119   temp_mt_entry->options = options;
120   if ( device ) {
121     temp_mt_entry->dev =
122       (char *)temp_mt_entry + sizeof( rtems_filesystem_mount_table_entry_t );
123     strcpy( temp_mt_entry->dev, device );
124   } else
125     temp_mt_entry->dev = 0;
126
127  /*
128   *  The mount_point should be a directory with read/write/execute
129   *  permissions in the existing tree.
130   */
131
132  if ( mount_point ) {
133
134    if ( rtems_filesystem_evaluate_path(
135            mount_point, RTEMS_LIBIO_PERMS_RWX, &loc, TRUE ) == -1 )
136      goto cleanup_and_bail;
137
138    /*
139     *  Test to see if it is a directory
140     */
141
142    loc_to_free = &loc;
143    if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
144      errno = ENOTDIR;
145      goto cleanup_and_bail;
146    }
147
148    /*
149     *  You can only mount one file system onto a single mount point.
150     */
151
152    if ( Is_node_fs_root(  &loc ) ){
153      errno = EBUSY;
154      goto cleanup_and_bail;
155    }
156 
157    /*
158     *  This must be a good mount point, so move the location information
159     *  into the allocated mount entry.  Note:  the information that
160     *  may have been allocated in loc should not be sent to freenode
161     *  until the system is unmounted.  It may be needed to correctly
162     *  traverse the tree.
163     */
164
165    temp_mt_entry->mt_point_node.node_access = loc.node_access;
166    temp_mt_entry->mt_point_node.handlers = loc.handlers;
167    temp_mt_entry->mt_point_node.ops = loc.ops;
168    temp_mt_entry->mt_point_node.mt_entry = loc.mt_entry;
169
170    /*
171     *  This link to the parent is only done when we are dealing with system
172     *  below the base file system
173     */
174
175    if ( !loc.ops->mount_h ){
176      errno = ENOTSUP;
177      goto cleanup_and_bail;
178    }
179
180    if ( loc.ops->mount_h( temp_mt_entry ) ) {
181      goto cleanup_and_bail;
182    }
183  } else {
184
185    /*
186     *  This is a mount of the base file system --> The
187     *  mt_point_node.node_access will be set to null to indicate that this
188     *  is the root of the entire file system.
189     */
190
191    temp_mt_entry->mt_fs_root.node_access = NULL;
192    temp_mt_entry->mt_fs_root.handlers = NULL;
193    temp_mt_entry->mt_fs_root.ops = NULL;
194
195    temp_mt_entry->mt_point_node.node_access = NULL;
196    temp_mt_entry->mt_point_node.handlers = NULL;
197    temp_mt_entry->mt_point_node.ops = NULL;
198    temp_mt_entry->mt_point_node.mt_entry = NULL;
199  }
200
201  if ( !fs_ops->fsmount_me_h ) {
202    errno = ENOTSUP;
203    goto cleanup_and_bail;
204  }
205
206  if ( fs_ops->fsmount_me_h( temp_mt_entry ) )
207    goto cleanup_and_bail;
208
209  /*
210   *  Add the mount table entry to the mount table chain
211   */
212
213  Chain_Append( &rtems_filesystem_mount_table_control, &temp_mt_entry->Node );
214
215  *mt_entry = temp_mt_entry;
216
217  return 0;
218
219cleanup_and_bail:
220
221  free( temp_mt_entry );
222 
223  if ( loc_to_free )
224    rtems_filesystem_freenode( loc_to_free );
225
226  return -1;
227}
228
229
230
231/*
232 *  init_fs_mount_table
233 *
234 *  This routine will initialize the chain control element that manages the
235 *  mount table chain.
236 */
237
238int init_fs_mount_table()
239{
240  Chain_Initialize_empty ( &rtems_filesystem_mount_table_control );
241  return 0;
242}
243
244/*
245 *  Is_node_fs_root
246 *
247 *  This routine will run through the entries that currently exist in the
248 *  mount table chain. For each entry in the mount table chain it will
249 *  compare the mount tables root node to the node describing the selected
250 *  mount point. If any match is found true is returned else false is
251 *  returned.
252 *
253 */
254
255static int Is_node_fs_root(
256  rtems_filesystem_location_info_t  *loc
257)
258{
259  Chain_Node                           *the_node;
260  rtems_filesystem_mount_table_entry_t *the_mount_entry;
261
262  /*
263   * For each mount table entry
264   */
265
266  for ( the_node = rtems_filesystem_mount_table_control.first;
267        !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
268        the_node = the_node->next ) {
269     the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
270     if ( the_mount_entry->mt_fs_root.node_access  == loc->node_access )
271        return TRUE;
272  }
273  return FALSE;
274}
Note: See TracBrowser for help on using the repository browser.