source: rtems/cpukit/libcsupport/src/mount.c @ 556ea0e3

4.104.114.84.95
Last change on this file since 556ea0e3 was 556ea0e3, checked in by Joel Sherrill <joel.sherrill@…>, on 05/27/99 at 16:12:20

Removed usage of printf.

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