source: rtems/cpukit/libcsupport/src/mount.c @ bf61751c

4.104.114.84.95
Last change on this file since bf61751c was bf61751c, checked in by Jennifer Averett <Jennifer.Averett@…>, on 10/23/02 at 18:10:27

2002-10-23 <strauman@…>

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