source: rtems/c/src/exec/libcsupport/src/mount.c @ bde7e18e

4.104.114.84.95
Last change on this file since bde7e18e was bde7e18e, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 20, 2000 at 1:29:21 PM

2000-11-20 Dmitry Kargapolov <dk@…>

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