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

4.104.114.84.95
Last change on this file since d1ee44e was 07a3253d, checked in by Joel Sherrill <joel.sherrill@…>, on 11/23/98 at 19:07:58

Added base version of file system infrastructure. This includes a major
overhaul of the RTEMS system call interface. This base file system is
the "In-Memory File System" aka IMFS.

The design and implementation was done by the following people:

+ Joel Sherrill (joel@…)
+ Jennifer Averett (jennifer@…)
+ Steve "Mr Mount" Salitasc (salitasc@…)
+ Kerwin Wade (wade@…)

PROBLEMS
========

+ It is VERY likely that merging this will break the UNIX port. This

can/will be fixed.

+ There is likely some reentrancy/mutual exclusion needed.

+ Eventually, there should be a "mini-IMFS" description table to

eliminate links, symlinks, etc to save memory. All you need to
have "classic RTEMS" functionality is technically directories
and device IO. All the rest could be left out to save memory.

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