source: rtems/cpukit/libcsupport/src/mount.c @ 29e92b0

4.104.11
Last change on this file since 29e92b0 was 29e92b0, checked in by Chris Johns <chrisj@…>, on May 31, 2010 at 1:56:37 PM

2010-05-31 Chris Johns <chrisj@…>

  • libcsupport/Makefile.am: Add mount-mgr.c.
  • libcsupport/src/mount-mgr.c: New.
  • include/rtems/fs.h: Added rtems_filesystem_location_mount.
  • libcsupport/include/rtems/libio.h, libcsupport/src/mount.c: New mount interface. It is similar to Linux.
  • libcsupport/include/rtems/libio_.h: Remove the init_fs_mount_table call.
  • libcsupport/src/base_fs.c: Remove init_fs_mount_table_call. Use the new mount call. Remove setting the root node in the global pathloc. Mount does this now.
  • libcsupport/src/privateenv.c: Remove the hack to set the root mount table entry in the environment.
  • libcsupport/src/unmount.cL Free the target string.
  • libblock/src/bdpart-mount.c: New mount API.
  • libfs/src/devfs/devfs.h, libfs/src/devfs/devfs_init.c, libfs/src/dosfs/dosfs.h, libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_init.c, libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_init.c, libfs/src/imfs/miniimfs_init.c, libfs/src/nfsclient/src/librtemsNfs.h, libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs.h, libnetworking/lib/ftpfs.c, libnetworking/rtems/ftpfs.h, libnetworking/rtems/tftp.h: New mount_h API.
  • libfs/src/devfs/devfs_eval.c: Local include of extern ops.
  • libfs/src/nfsclient/src/nfs.c: New mount API. Removed the mount me call and fixed the initialisation to happen when mounting.
  • libmisc/Makefile.am, libmisc/shell/shellconfig.h: Remove mount filesystem files.
  • libmisc/fsmount/fsmount.c, libmisc/fsmount/fsmount.h: Updated to the new mount table values.
  • libmisc/shell/main_mount_ftp.c, libmisc/shell/main_mount_msdos.c, libmisc/shell/main_mount_rfs.c, libmisc/shell/main_mount_tftp.c: Removed.
  • libmisc/shell/main_mount.c: Use the new mount API. Also access the file system table for the file system types.
  • libnetworking/lib/tftpDriver.c: Updated to the new mount API. Fixed to allow mounting from any mount point. Also can now have more than file system mounted.
  • sapi/include/confdefs.h: Add file system configuration support.
  • Property mode set to 100644
File size: 8.8 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.rtems.com/license/LICENSE.
16 *
17 *  $Id$
18 */
19
20#if HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <rtems/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
34#include <rtems/libio_.h>
35
36/*
37 * External defined by confdefs.h or the user.
38 */
39extern const rtems_filesystem_table_t configuration_filesystem_table[];
40
41/*
42 * Points to a list of filesystems added at runtime.
43 */
44rtems_chain_control *rtems_filesystem_table;
45
46/*
47 * Mount table list.
48 */
49rtems_chain_control rtems_filesystem_mount_table_control;
50bool                rtems_filesystem_mount_table_control_init;
51
52/*
53 * Default pathconfs.
54 */
55const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf = {
56   5,    /* link_max: count */
57   128,  /* max_canon: max formatted input line size */
58   7,    /* max_input: max input line size */
59   255,  /* name_max: max name */
60   255,  /* path_max: max path */
61   1024, /* pipe_buf: pipe buffer size */
62   0,    /* posix_async_io: async IO supported on fs, 0=no, 1=yes */
63   0 ,   /* posix_chown_restrictions: can chown: 0=no, 1=yes */
64   1,    /* posix_no_trunc: error on filenames > max name, 0=no, 1=yes */
65   0,    /* posix_prio_io: priority IO, 0=no, 1=yes */
66   0,    /* posix_sync_io: file can be sync'ed, 0=no, 1=yes */
67   0     /* posix_vdisable: special char processing, 0=no, 1=yes */
68};
69
70/*
71 *  Is_node_fs_root
72 *
73 *  This routine will run through the entries that currently exist in the
74 *  mount table chain. For each entry in the mount table chain it will
75 *  compare the mount tables root node to the node describing the selected
76 *  mount point. If any match is found true is returned else false is
77 *  returned.
78 *
79 */
80
81static bool Is_node_fs_root(
82  rtems_filesystem_location_info_t  *loc
83)
84{
85  rtems_chain_node                     *the_node;
86  rtems_filesystem_mount_table_entry_t *the_mount_entry;
87
88  /*
89   * For each mount table entry
90   */
91  if ( rtems_filesystem_mount_table_control_init ) {
92    for ( the_node = rtems_chain_first( &rtems_filesystem_mount_table_control );
93          !rtems_chain_is_tail( &rtems_filesystem_mount_table_control, the_node );
94          the_node = rtems_chain_next( the_node ) ) {
95      the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
96      if ( the_mount_entry->mt_fs_root.node_access  == loc->node_access )
97        return true;
98    }
99  }
100  return false;
101}
102
103/*
104 *  mount
105 *
106 *  This routine will attempt to mount a new file system at the specified
107 *  mount point. A series of tests will be run to determine if any of the
108 *  following reasons exist to prevent the mount operation:
109 *
110 *      1) The file system type or options are not valid
111 *      2) No new file system root node is specified
112 *      3) The selected file system has already been mounted
113 *      4) The mount point exists with the proper permissions to allow mounting
114 *      5) The selected mount point already has a file system mounted to it
115 *
116 */
117
118int mount(
119  const char                 *source,
120  const char                 *target,
121  const char                 *filesystemtype,
122  rtems_filesystem_options_t options,
123  const void                 *data
124          )
125{
126  const rtems_filesystem_table_t       *entry;
127  rtems_filesystem_location_info_t      loc;
128  rtems_filesystem_mount_table_entry_t *mt_entry = NULL;
129  rtems_filesystem_location_info_t     *loc_to_free = NULL;
130  size_t size;
131
132  /*
133   * If mount is ever called we allocate the mount table control structure.
134   */
135  if ( !rtems_filesystem_mount_table_control_init ) {
136    rtems_filesystem_mount_table_control_init = true;
137    rtems_chain_initialize_empty ( &rtems_filesystem_mount_table_control );
138  }
139
140  /*
141   *  Are the file system options valid?
142   */
143
144  if ( options != RTEMS_FILESYSTEM_READ_ONLY &&
145       options != RTEMS_FILESYSTEM_READ_WRITE ) {
146    errno = EINVAL;
147    return -1;
148  }
149
150  /*
151   * Check the type.
152   */
153  if (!filesystemtype) {
154    errno = EINVAL;
155    return -1;
156  }
157
158  if (strlen(filesystemtype) >= 128) {
159    errno = EINVAL;
160    return -1;
161  }
162   
163  /*
164   * Check the configuration table filesystems then check any runtime added
165   * file systems.
166   */
167  entry = &configuration_filesystem_table[0];
168  while (entry->type) {
169    if (strcmp (filesystemtype, entry->type) == 0)
170      break;
171    ++entry;
172  }
173 
174  if (!entry->type) {
175    entry = NULL;
176    if (rtems_filesystem_table) {
177      rtems_chain_node *the_node;
178      for (the_node = rtems_chain_first(rtems_filesystem_table);
179           !rtems_chain_is_tail(rtems_filesystem_table, the_node);
180           the_node = rtems_chain_next(the_node)) {
181        entry = &(((rtems_filesystem_table_node_t*) the_node)->entry);
182        if (strcmp (filesystemtype, entry->type) == 0)
183          break;
184        entry = NULL;
185      }
186    }
187  }
188
189  if (!entry)
190  {
191    errno = EINVAL;
192    return -1;
193  }
194 
195  /*
196   * Allocate a mount table entry
197   */
198
199  size = sizeof(rtems_filesystem_mount_table_entry_t);
200  if ( source )
201    size += strlen( source ) + 1;
202   
203  mt_entry = malloc( size );
204  if ( !mt_entry ) {
205    errno = ENOMEM;
206    return -1;
207  }
208
209  memset( mt_entry, 0, size );
210   
211  mt_entry->mt_fs_root.mt_entry = mt_entry;
212  mt_entry->type = entry->type;
213  mt_entry->options = options;
214  mt_entry->pathconf_limits_and_options = rtems_filesystem_default_pathconf;
215   
216  if ( source ) {
217    mt_entry->dev =
218      (char *)mt_entry + sizeof( rtems_filesystem_mount_table_entry_t );
219    strcpy( mt_entry->dev, source );
220  } else
221    mt_entry->dev = 0;
222
223  /*
224   *  The mount_point should be a directory with read/write/execute
225   *  permissions in the existing tree.
226   */
227
228  if ( target ) {
229
230    if ( rtems_filesystem_evaluate_path(
231           target, strlen( target ), RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 )
232      goto cleanup_and_bail;
233
234    loc_to_free = &loc;
235
236    /*
237     * Test for node_type_h
238     */
239
240    if (!loc.ops->node_type_h) {
241      errno =  ENOTSUP;
242      goto cleanup_and_bail;
243    }
244
245    /*
246     *  Test to see if it is a directory
247     */
248
249    if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
250      errno = ENOTDIR;
251      goto cleanup_and_bail;
252    }
253
254    /*
255     *  You can only mount one file system onto a single mount point.
256     */
257
258    if ( Is_node_fs_root(  &loc ) ){
259      errno = EBUSY;
260      goto cleanup_and_bail;
261    }
262
263    /*
264     *  This must be a good mount point, so move the location information
265     *  into the allocated mount entry.  Note:  the information that
266     *  may have been allocated in loc should not be sent to freenode
267     *  until the system is unmounted.  It may be needed to correctly
268     *  traverse the tree.
269     */
270
271    mt_entry->mt_point_node.node_access = loc.node_access;
272    mt_entry->mt_point_node.handlers = loc.handlers;
273    mt_entry->mt_point_node.ops = loc.ops;
274    mt_entry->mt_point_node.mt_entry = loc.mt_entry;
275     
276    /*
277     *  This link to the parent is only done when we are dealing with system
278     *  below the base file system
279     */
280
281    if ( !loc.ops->mount_h ){
282      errno = ENOTSUP;
283      goto cleanup_and_bail;
284    }
285
286    if ( loc.ops->mount_h( mt_entry ) ) {
287      goto cleanup_and_bail;
288    }
289
290    mt_entry->target = strdup( target );
291  } else {
292
293    /*
294     * Do we already have a base file system ?
295     */
296    if ( !rtems_chain_is_empty( &rtems_filesystem_mount_table_control ) ) {
297      errno = EINVAL;
298      goto cleanup_and_bail;
299    }
300   
301    /*
302     *  This is a mount of the base file system --> The
303     *  mt_point_node.node_access will be set to null to indicate that this
304     *  is the root of the entire file system.
305     */
306
307    mt_entry->mt_fs_root.node_access = NULL;
308    mt_entry->mt_fs_root.handlers = NULL;
309    mt_entry->mt_fs_root.ops = NULL;
310
311    mt_entry->mt_point_node.node_access = NULL;
312    mt_entry->mt_point_node.handlers = NULL;
313    mt_entry->mt_point_node.ops = NULL;
314    mt_entry->mt_point_node.mt_entry = NULL;
315
316    mt_entry->target = "/";
317  }
318
319  if ( entry->mount_h( mt_entry, data ) ) {
320    /*
321     * Try to undo the mount operation
322     */
323    if ( loc.ops->unmount_h ) {
324      loc.ops->unmount_h( mt_entry );
325    }
326    goto cleanup_and_bail;
327  }
328
329  /*
330   *  Add the mount table entry to the mount table chain
331   */
332  rtems_chain_append( &rtems_filesystem_mount_table_control,
333                      &mt_entry->Node );
334
335  if ( !target )
336    rtems_filesystem_root = mt_entry->mt_fs_root;
337
338  return 0;
339
340cleanup_and_bail:
341
342  free( (void*) mt_entry->target );
343  free( mt_entry );
344
345  if ( loc_to_free )
346    rtems_filesystem_freenode( loc_to_free );
347
348  return -1;
349}
350
Note: See TracBrowser for help on using the repository browser.