source: rtems/c/src/lib/libc/unmount.c @ bde9bb5

4.104.114.84.95
Last change on this file since bde9bb5 was 2a929cc, checked in by Joel Sherrill <joel.sherrill@…>, on 01/25/01 at 15:59:58

2001-01-25 Fernando Ruiz <fernando.ruiz@…>

  • Alternate email is correo@…
  • libc/privateenv.c: New file.
  • include/rtems/libio_.h, libc/Makefile.am, libc/base_fs.c, libc/unmount.c: Moved default umask, current working directory, root, and links followed count into a structure "user environment" that can then be treated as a unit. This enable giving unique copies of these to individual threads or collection of threads.
  • Property mode set to 100644
File size: 5.0 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.OARcorp.com/rtems/license.html.
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 <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
35/*
36 *  Data structures and routines private to mount/unmount pair.
37 */
38
39extern Chain_Control                    rtems_filesystem_mount_table_control;
40
41int search_mt_for_mount_point(
42  rtems_filesystem_location_info_t *location_of_mount_point
43);
44
45
46int file_systems_below_this_mountpoint(
47  const char                            *path,
48  rtems_filesystem_location_info_t      *temp_loc,
49  rtems_filesystem_mount_table_entry_t  *temp_mt_entry
50);
51
52/*
53 *  unmount
54 *
55 *  This routine will attempt to unmount the file system that has been
56 *  is mounted a path.  If the operation is successful, 0 will
57 *  be returned to the calling routine.  Otherwise, 1 will be returned.
58 */
59
60int unmount(
61  const char *path
62)
63{
64  int                                   status;
65  rtems_filesystem_location_info_t      fs_root_loc;
66  rtems_filesystem_mount_table_entry_t  temp_mt_entry;
67
68  /*
69   *  Are there any file systems below the path specified
70   */
71
72  status = file_systems_below_this_mountpoint(
73    path,
74    &fs_root_loc,
75    &temp_mt_entry
76  );
77
78  if ( status != 0 )
79    return -1;
80
81  /*
82   *  Is the current node reference pointing to a node in the file system
83   *  we are attempting to unmount ?
84   */
85
86  if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) {
87    rtems_filesystem_freenode( &fs_root_loc );
88    set_errno_and_return_minus_one( EBUSY );
89  }
90
91  /*
92   *  Run the file descriptor table to determine if there are any file
93   *  descriptors that are currently active and reference nodes in the
94   *  file system that we are trying to unmount
95   */
96
97  if ( rtems_libio_is_open_files_in_fs( fs_root_loc.mt_entry ) == 1 ) {
98    rtems_filesystem_freenode( &fs_root_loc );
99    set_errno_and_return_minus_one( EBUSY );
100  }
101 
102  /*
103   * Allow the file system being unmounted on to do its cleanup.
104   */
105
106  if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) {
107    rtems_filesystem_freenode( &fs_root_loc );
108    return -1;
109  }
110
111  /*
112   * Run the unmount function for the subordinate file system.
113   */
114
115  if ((temp_mt_entry.mt_fs_root.ops->fsunmount_me_h )( fs_root_loc.mt_entry ) != 0){
116    rtems_filesystem_freenode( &fs_root_loc );
117    return -1;
118  }
119
120  /*
121   *  Extract the mount table entry from the chain
122   */
123
124  Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry );
125
126  /*
127   *  Free the memory associated with the extracted mount table entry.
128   */
129
130  rtems_filesystem_freenode( &fs_root_loc.mt_entry->mt_point_node );
131  free( fs_root_loc.mt_entry );
132  rtems_filesystem_freenode( &fs_root_loc );
133
134  return 0;
135}
136
137
138/*
139 *  file_systems_below_this_mountpoint
140 *
141 *  This routine will run through the entries that currently exist in the
142 *  mount table chain. For each entry in the mount table chain it will
143 *  compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
144 *  mount table file system root nodes matches the new file system root node
145 *  this indicates that we are trying to mount a file system that has already
146 *  been mounted. This is not a permitted operation. temp_loc is set to
147 *  the root node of the file system being unmounted.
148 */
149
150int file_systems_below_this_mountpoint(
151  const char                            *path,
152  rtems_filesystem_location_info_t      *fs_root_loc,
153  rtems_filesystem_mount_table_entry_t  *fs_to_unmount
154)
155{
156  Chain_Node                           *the_node;
157  rtems_filesystem_mount_table_entry_t *the_mount_entry;
158
159  /*
160   *  Is the path even a valid node name in the existing tree?
161   */
162
163  if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) )
164    return -1;
165 
166  /*
167   * Verify this is the root node for the file system to be unmounted.
168   */
169
170  *fs_to_unmount = *fs_root_loc->mt_entry;
171  if ( fs_to_unmount->mt_fs_root.node_access != fs_root_loc->node_access )
172    set_errno_and_return_minus_one( EACCES );
173
174  /*
175   * Search the mount table for any mount entries referencing this
176   * mount entry.
177   */
178
179  for ( the_node = rtems_filesystem_mount_table_control.first;
180        !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
181        the_node = the_node->next ) {
182     the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
183     if (the_mount_entry->mt_point_node.mt_entry  == fs_root_loc->mt_entry ) {
184          set_errno_and_return_minus_one( EBUSY );
185     }
186  }
187
188  return 0;
189}
Note: See TracBrowser for help on using the repository browser.