source: rtems/cpukit/libcsupport/src/unmount.c @ e8cec9e

4.10
Last change on this file since e8cec9e was 3d3a18e6, checked in by Sebastian Huber <sebastian.huber@…>, on 07/01/10 at 14:39:39

2010-06-10 Sebastian Huber <sebastian.huber@…>

  • libcsupport/src/unmount.c: Removed obsolete declarations. Fixed invalid memory free.

2010-06-10 Sebastian Huber <sebastian.huber@…>

  • libnetworking/rtems/ftpfs.h, libnetworking/lib/ftpfs.c: Removed rtems_ftpfs_mount().

2010-06-10 Sebastian Huber <sebastian.huber@…>

  • libcsupport/src/mount-mktgt.c: New file.
  • libcsupport/Makefile.am: Reflect change above.
  • libcsupport/include/rtems/libio.h: Declare mount_and_make_target_path().

2010-06-09 Sebastian Huber <sebastian.huber@…>

  • libnetworking/rtems/ftpfs.h, libnetworking/lib/ftpfs.c: Added rtems_ftpfs_mount() again. Documentation.

2010-06-09 Sebastian Huber <sebastian.huber@…>

  • libcsupport/include/rtems/libio.h, sapi/include/confdefs.h: Added and use defines for file system types.

2010-06-09 Sebastian Huber <sebastian.huber@…>

  • libcsupport/src/mount.c: Fixed NULL pointer access.
  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  unmount() - Unmount a File System
3 *
4 *  This routine is not defined in the POSIX 1003.1b standard but
5 *  in some form is supported on most UNIX and POSIX systems.  This
6 *  routine is necessary to mount instantiations of a file system
7 *  into the file system name space.
8 *
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <rtems/chain.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <errno.h>
29#include <stdlib.h>
30#include <string.h>
31#include <assert.h>
32
33#include <rtems/libio_.h>
34#include <rtems/seterr.h>
35
36bool rtems_filesystem_nodes_equal(
37  const rtems_filesystem_location_info_t   *loc1,
38  const rtems_filesystem_location_info_t   *loc2
39){
40  return ( loc1->node_access == loc2->node_access );
41}
42
43
44/*
45 *  file_systems_below_this_mountpoint
46 *
47 *  This routine will run through the entries that currently exist in the
48 *  mount table chain. For each entry in the mount table chain it will
49 *  compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
50 *  mount table file system root nodes matches the new file system root node
51 *  this indicates that we are trying to mount a file system that has already
52 *  been mounted. This is not a permitted operation. temp_loc is set to
53 *  the root node of the file system being unmounted.
54 */
55
56bool file_systems_below_this_mountpoint(
57  const char                            *path __attribute__((unused)),
58  rtems_filesystem_location_info_t      *fs_root_loc,
59  rtems_filesystem_mount_table_entry_t  *fs_to_unmount __attribute__((unused))
60)
61{
62  rtems_chain_node                     *the_node;
63  rtems_filesystem_mount_table_entry_t *the_mount_entry;
64
65  /*
66   * Search the mount table for any mount entries referencing this
67   * mount entry.
68   */
69
70  for ( the_node = rtems_filesystem_mount_table_control.first;
71        !rtems_chain_is_tail( &rtems_filesystem_mount_table_control, the_node );
72        the_node = the_node->next ) {
73     the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
74     if (the_mount_entry->mt_point_node.mt_entry  == fs_root_loc->mt_entry ) {
75        return true;
76     }
77  }
78
79  return false;
80}
81
82/*
83 *  unmount
84 *
85 *  This routine will attempt to unmount the file system that has been
86 *  is mounted a path.  If the operation is successful, 0 will
87 *  be returned to the calling routine.  Otherwise, 1 will be returned.
88 */
89
90int unmount(
91  const char *path
92)
93{
94  rtems_filesystem_location_info_t      loc;
95  rtems_filesystem_location_info_t     *fs_root_loc;
96  rtems_filesystem_location_info_t     *fs_mount_loc;
97  rtems_filesystem_mount_table_entry_t *mt_entry;
98
99  /*
100   *  Get
101   *    The root node of the mounted filesytem.
102   *    The node for the directory that the fileystem is mounted on.
103   *    The mount entry that is being refered to.
104   */
105
106  if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x0, &loc, true ) )
107    return -1;
108
109  mt_entry     = loc.mt_entry;
110  fs_mount_loc = &mt_entry->mt_point_node;
111  fs_root_loc  = &mt_entry->mt_fs_root;
112
113  /*
114   * Verify this is the root node for the file system to be unmounted.
115   */
116
117  if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
118    rtems_filesystem_freenode( &loc );
119    rtems_set_errno_and_return_minus_one( EACCES );
120  }
121
122  /*
123   * Free the loc node and just use the nodes from the mt_entry .
124   */
125
126  rtems_filesystem_freenode( &loc );
127
128  /*
129   * Verify Unmount is supported by both filesystems.
130   */
131
132  if ( !fs_mount_loc->ops->unmount_h )
133    rtems_set_errno_and_return_minus_one( ENOTSUP );
134
135  if ( !fs_root_loc->ops->fsunmount_me_h )
136    rtems_set_errno_and_return_minus_one( ENOTSUP );
137
138
139  /*
140   *  Verify the current node is not in this filesystem.
141   *  XXX - Joel I have a question here wasn't code added
142   *        that made the current node thread based instead
143   *        of system based?  I thought it was but it doesn't
144   *        look like it in this version.
145   */
146
147  if ( rtems_filesystem_current.mt_entry == mt_entry )
148    rtems_set_errno_and_return_minus_one( EBUSY );
149
150  /*
151   *  Verify there are no file systems below the path specified
152   */
153
154  if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
155    rtems_set_errno_and_return_minus_one( EBUSY );
156
157  /*
158   *  Run the file descriptor table to determine if there are any file
159   *  descriptors that are currently active and reference nodes in the
160   *  file system that we are trying to unmount
161   */
162
163  if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
164    rtems_set_errno_and_return_minus_one( EBUSY );
165
166  /*
167   * Allow the file system being unmounted on to do its cleanup.
168   * If it fails it will set the errno to the approprate value
169   * and the fileystem will not be modified.
170   */
171
172  if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
173    return -1;
174
175  /*
176   *  Allow the mounted filesystem to unmark the use of the root node.
177   *
178   *  Run the unmount function for the subordinate file system.
179   *
180   *  If we fail to unmount the filesystem remount it on the base filesystems
181   *  directory node.
182   *
183   *  NOTE:  Fatal error is called in a case which should never happen
184   *         This was response was questionable but the best we could
185   *         come up with.
186   */
187
188  if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
189    if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
190      rtems_fatal_error_occurred( 0 );
191    return -1;
192  }
193
194  /*
195   *  Extract the mount table entry from the chain
196   */
197
198  rtems_chain_extract( ( rtems_chain_node * ) mt_entry );
199
200  /*
201   *  Free the memory node that was allocated in mount
202   *  Free the memory associated with the extracted mount table entry.
203   */
204
205  rtems_filesystem_freenode( fs_mount_loc );
206  free( mt_entry );
207
208  return 0;
209}
Note: See TracBrowser for help on using the repository browser.