source: rtems/cpukit/libcsupport/src/mount.c @ 2f87c843

4.104.114.84.9
Last change on this file since 2f87c843 was 2f87c843, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 5, 1999 at 12:28:43 AM

Corrected spacing and added some new error checks that were needed
to avoid dereferencing NULLs.

  • Property mode set to 100644
File size: 7.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-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   *  Is there a file system operations table?
105   */
106
107  if ( fs_ops == NULL ) {
108    errno = EINVAL;
109    return -1;
110  }
111
112  /*
113   *  Are the file system options valid?
114   */
115
116  if ( fsoptions == NULL ) {
117    errno = EINVAL;
118    return -1;
119  }
120
121  options = get_file_system_options( fsoptions );
122  if ( options == RTEMS_FILESYSTEM_BAD_OPTIONS ) {
123    errno = EINVAL;
124    return -1;
125  }
126
127  /*
128   * Allocate a mount table entry
129   */
130
131   temp_mt_entry = malloc( sizeof(rtems_filesystem_mount_table_entry_t) );
132
133   if ( !temp_mt_entry ) {
134     errno = ENOMEM;
135     return -1;
136   }
137
138   temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry;
139   temp_mt_entry->options = options;
140   if ( device )
141     sprintf( temp_mt_entry->dev, "%s", device );
142   else
143     temp_mt_entry->dev = 0;
144
145  /*
146   *  The mount_point should be a directory with read/write/execute
147   *  permissions in the existing tree.
148   */
149
150  if ( mount_point ) {
151     if ( rtems_filesystem_evaluate_path( 
152       mount_point, 
153       RTEMS_LIBIO_PERMS_RWX,
154       &temp_loc ,
155       TRUE ) == -1 )
156       goto cleanup_and_bail;
157
158     /*
159      * Test to see if it is a directory
160      */
161
162     if ( temp_loc.ops->node_type( &temp_loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
163       errno = ENOTDIR;
164       goto cleanup_and_bail;
165     }
166
167     /*
168      *  You can only mount one file system onto a single mount point.
169      */
170
171     if ( search_mt_for_mount_point( &temp_loc ) == FOUND ) {
172       errno = EBUSY;
173       goto cleanup_and_bail;
174     }
175 
176     /*
177      * This must be a good mount point, so move the location information
178      * into the allocated mount entry
179      */
180
181     temp_mt_entry->mt_point_node.node_access = temp_loc.node_access;
182     temp_mt_entry->mt_point_node.handlers = temp_loc.handlers;
183     temp_mt_entry->mt_point_node.ops = temp_loc.ops;
184     temp_mt_entry->mt_point_node.mt_entry = temp_loc.mt_entry;
185
186     /*
187      * This link to the parent is only done when we are dealing with system
188      * below the base file system
189      */
190
191     if ( !temp_loc.ops->mount ){
192       errno = ENOTSUP;
193       goto cleanup_and_bail;
194     }
195
196     if ( temp_loc.ops->mount( temp_mt_entry ) ) {
197        goto cleanup_and_bail;
198     }
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  return 0;
234
235cleanup_and_bail:
236
237  free( temp_mt_entry );
238  return -1;
239}
240
241
242
243/*
244 *  init_fs_mount_table
245 *
246 *  This routine will initialize the chain control element that manages the
247 *  mount table chain.
248 */
249
250int init_fs_mount_table()
251{
252  Chain_Initialize_empty ( &rtems_filesystem_mount_table_control );
253  return 0;
254}
255
256/*
257 *  get_file_system_options
258 *
259 *  This routine will determine is the text string that represents the options
260 *  that are to be used to mount the file system are actually valid. If the
261 *  options are valid the appropriate file system options type will be returned
262 *  to the calling routine.
263 */
264
265rtems_filesystem_options_t get_file_system_options(
266  char *fsoptions
267)
268{
269  if ( strcmp( "RO", strupr( fsoptions ) ) == 0 )
270    return RTEMS_FILESYSTEM_READ_ONLY;
271  if ( strcmp( "RW", strupr( fsoptions ) ) == 0 )
272    return RTEMS_FILESYSTEM_READ_WRITE_ONLY;
273  else
274    return RTEMS_FILESYSTEM_BAD_OPTIONS;
275}
276
277
278
279/*
280 *  search_mt_for_mount_point
281 *
282 *  This routine will run through the entries that currently exist in the
283 *  mount table chain. For each entry in the mount table chain it will
284 *  compare the mount tables mt_point_node to the node describing the selected
285 *  mount point.. If any of the mount table file system mount point nodes
286 *  match the new file system selected mount point node, we are attempting
287 *  to mount the new file system onto a node that already has a file system
288 *  mounted to it. This is not a permitted operation.
289 */
290
291int search_mt_for_mount_point(
292  rtems_filesystem_location_info_t *location_of_mount_point
293)
294{
295  Chain_Node                           *the_node;
296  rtems_filesystem_mount_table_entry_t *the_mount_entry;
297
298  for ( the_node = rtems_filesystem_mount_table_control.first;
299        !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
300        the_node = the_node->next ) {
301
302     the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
303     if ( the_mount_entry->mt_point_node.node_access  == 
304             location_of_mount_point->node_access )
305        return FOUND;
306  }
307  return NOT_FOUND;
308}
309
Note: See TracBrowser for help on using the repository browser.