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

Last change on this file since e5aeae7b was e5aeae7b, checked in by Joel Sherrill <joel.sherrill@…>, on 11/20/00 at 13:30:03

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: 7.1 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 "libio_.h"
31
32Chain_Control rtems_filesystem_mount_table_control;
33
34#include "imfs.h"
35
36/* XXX this structure should be in an IMFS specific file */
37/* XXX this structure should use real constants */
38
39rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS = {
40   5,   /* link_max */
41   6,   /* max_canon */
42   7,   /* max_input */
43   IMFS_NAME_MAX,       /* name_max */
44   255, /* path_max */
45   2,   /* pipe_buf */
46   1,   /* posix_async_io */
47   2,   /* posix_chown_restrictions */
48   3,   /* posix_no_trunc */
49   4,   /* posix_prio_io */
50   5,   /* posix_sync_io */
51   6    /* posix_vdisable */
52};
53
54/*
55 *  XXX
56 */
57
58int search_mt_for_mount_point(
59  rtems_filesystem_location_info_t *location_of_mount_point
60);
61
62int init_fs_mount_table( void );
63
64
65/*
66 *  XXX
67 */
68
69#define FOUND      0
70#define NOT_FOUND -1
71
72/*
73 *  mount
74 *
75 *  This routine will attempt to mount a new file system at the specified
76 *  mount point. A series of tests will be run to determine if any of the
77 *  following reasons exist to prevent the mount operation:
78 *
79 *      1) The file system type or options are not valid
80 *      2) No new file system root node is specified
81 *      3) The selected file system has already been mounted
82 *      4) The mount point exists with the proper permissions to allow mounting
83 *      5) The selected mount point already has a file system mounted to it
84 *
85 */
86
87int mount(
88  rtems_filesystem_mount_table_entry_t **mt_entry,
89  rtems_filesystem_operations_table    *fs_ops,
90  rtems_filesystem_options_t            options,
91  char                                 *device,
92  char                                 *mount_point
93)
94{
95  rtems_filesystem_location_info_t      loc;
96  rtems_filesystem_mount_table_entry_t *temp_mt_entry;
97  rtems_filesystem_location_info_t     *loc_to_free = NULL;
98  size_t size;
99
100/* XXX add code to check for required operations */
101
102  /*
103   *  Is there a file system operations table?
104   */
105
106  if ( fs_ops == NULL ) {
107    errno = EINVAL;
108    return -1;
109  }
110
111  /*
112   *  Are the file system options valid?
113   */
114
115  if ( options != RTEMS_FILESYSTEM_READ_ONLY &&
116       options != RTEMS_FILESYSTEM_READ_WRITE ) {
117    errno = EINVAL;
118    return -1;
119  }
120
121  /*
122   * Allocate a mount table entry
123   */
124
125   size = sizeof(rtems_filesystem_mount_table_entry_t);
126   if ( device )
127     size += strlen( device ) + 1;
128   temp_mt_entry = malloc( size );
129
130   if ( !temp_mt_entry ) {
131     errno = ENOMEM;
132     return -1;
133   }
134
135   temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry;
136   temp_mt_entry->options = options;
137   if ( device ) {
138     temp_mt_entry->dev =
139       (char *)temp_mt_entry + sizeof( rtems_filesystem_mount_table_entry_t );
140     strcpy( temp_mt_entry->dev, device );
141   } else
142     temp_mt_entry->dev = 0;
143
144  /*
145   *  The mount_point should be a directory with read/write/execute
146   *  permissions in the existing tree.
147   */
148
149  if ( mount_point ) {
150
151    if ( rtems_filesystem_evaluate_path(
152            mount_point, RTEMS_LIBIO_PERMS_RWX, &loc, TRUE ) == -1 )
153      goto cleanup_and_bail;
154
155    /*
156     *  Test to see if it is a directory
157     */
158
159    loc_to_free = &loc;
160    if ( loc.ops->node_type( &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 ( search_mt_for_mount_point( &loc ) == FOUND ) {
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 ){
193      errno = ENOTSUP;
194      goto cleanup_and_bail;
195    }
196
197    if ( loc.ops->mount( 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 ) {
219    errno = ENOTSUP;
220    goto cleanup_and_bail;
221  }
222
223  if ( fs_ops->fsmount_me( temp_mt_entry ) )
224    goto cleanup_and_bail;
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/*
263 *  search_mt_for_mount_point
264 *
265 *  This routine will run through the entries that currently exist in the
266 *  mount table chain. For each entry in the mount table chain it will
267 *  compare the mount tables mt_point_node to the node describing the selected
268 *  mount point.. If any of the mount table file system mount point nodes
269 *  match the new file system selected mount point node, we are attempting
270 *  to mount the new file system onto a node that already has a file system
271 *  mounted to it. This is not a permitted operation.
272 */
273
274int search_mt_for_mount_point(
275  rtems_filesystem_location_info_t *location_of_mount_point
276)
277{
278  Chain_Node                           *the_node;
279  rtems_filesystem_mount_table_entry_t *the_mount_entry;
280
281  for ( the_node = rtems_filesystem_mount_table_control.first;
282        !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
283        the_node = the_node->next ) {
284
285     the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
286     if ( the_mount_entry->mt_point_node.node_access  ==
287             location_of_mount_point->node_access )
288        return FOUND;
289  }
290  return NOT_FOUND;
291}
292
Note: See TracBrowser for help on using the repository browser.