OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libcsupport/] [src/] [unmount.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 *  unmount.c,v 1.16 2002/01/04 18:29:37 joel Exp
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
#include <rtems/seterr.h>
35
 
36
/*
37
 *  Data structures and routines private to mount/unmount pair.
38
 */
39
 
40
extern Chain_Control                    rtems_filesystem_mount_table_control;
41
 
42
int search_mt_for_mount_point(
43
  rtems_filesystem_location_info_t *location_of_mount_point
44
);
45
 
46
rtems_boolean rtems_filesystem_nodes_equal(
47
  const rtems_filesystem_location_info_t   *loc1,
48
  const rtems_filesystem_location_info_t   *loc2
49
){
50
  return ( loc1->node_access == loc2->node_access );
51
}
52
 
53
 
54
/*
55
 *  file_systems_below_this_mountpoint
56
 *
57
 *  This routine will run through the entries that currently exist in the
58
 *  mount table chain. For each entry in the mount table chain it will
59
 *  compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
60
 *  mount table file system root nodes matches the new file system root node
61
 *  this indicates that we are trying to mount a file system that has already
62
 *  been mounted. This is not a permitted operation. temp_loc is set to
63
 *  the root node of the file system being unmounted.
64
 */
65
 
66
rtems_boolean file_systems_below_this_mountpoint(
67
  const char                            *path,
68
  rtems_filesystem_location_info_t      *fs_root_loc,
69
  rtems_filesystem_mount_table_entry_t  *fs_to_unmount
70
)
71
{
72
  Chain_Node                           *the_node;
73
  rtems_filesystem_mount_table_entry_t *the_mount_entry;
74
 
75
  /*
76
   * Search the mount table for any mount entries referencing this
77
   * mount entry.
78
   */
79
 
80
  for ( the_node = rtems_filesystem_mount_table_control.first;
81
        !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
82
        the_node = the_node->next ) {
83
     the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
84
     if (the_mount_entry->mt_point_node.mt_entry  == fs_root_loc->mt_entry ) {
85
        return TRUE;
86
     }
87
  }
88
 
89
  return FALSE;
90
}
91
 
92
/*
93
 *  unmount
94
 *
95
 *  This routine will attempt to unmount the file system that has been
96
 *  is mounted a path.  If the operation is successful, 0 will
97
 *  be returned to the calling routine.  Otherwise, 1 will be returned.
98
 */
99
 
100
int unmount(
101
  const char *path
102
)
103
{
104
  rtems_filesystem_location_info_t      loc;
105
  rtems_filesystem_location_info_t     *fs_root_loc;
106
  rtems_filesystem_location_info_t     *fs_mount_loc;
107
  rtems_filesystem_mount_table_entry_t *mt_entry;
108
 
109
  /*
110
   *  Get
111
   *    The root node of the mounted filesytem.
112
   *    The node for the directory that the fileystem is mounted on.
113
   *    The mount entry that is being refered to.
114
   */
115
 
116
  if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, TRUE ) )
117
    return -1;
118
 
119
  mt_entry     = loc.mt_entry;
120
  fs_mount_loc = &mt_entry->mt_point_node;
121
  fs_root_loc  = &mt_entry->mt_fs_root;
122
 
123
  /*
124
   * Verify this is the root node for the file system to be unmounted.
125
   */
126
 
127
  if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
128
    rtems_filesystem_freenode( &loc );
129
    rtems_set_errno_and_return_minus_one( EACCES );
130
  }
131
 
132
  /*
133
   * Free the loc node and just use the nodes from the mt_entry .
134
   */
135
 
136
  rtems_filesystem_freenode( &loc );
137
 
138
  /*
139
   * Verify Unmount is supported by both filesystems.
140
   */
141
 
142
  if ( !fs_mount_loc->ops->unmount_h )
143
    rtems_set_errno_and_return_minus_one( ENOTSUP );
144
 
145
  if ( !fs_root_loc->ops->fsunmount_me_h )
146
    rtems_set_errno_and_return_minus_one( ENOTSUP );
147
 
148
 
149
  /*
150
   *  Verify the current node is not in this filesystem.
151
   *  XXX - Joel I have a question here wasn't code added
152
   *        that made the current node thread based instead
153
   *        of system based?  I thought it was but it doesn't
154
   *        look like it in this version.
155
   */
156
 
157
  if ( rtems_filesystem_current.mt_entry == mt_entry )
158
    rtems_set_errno_and_return_minus_one( EBUSY );
159
 
160
  /*
161
   *  Verify there are no file systems below the path specified
162
   */
163
 
164
  if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
165
    rtems_set_errno_and_return_minus_one( EBUSY );
166
 
167
  /*
168
   *  Run the file descriptor table to determine if there are any file
169
   *  descriptors that are currently active and reference nodes in the
170
   *  file system that we are trying to unmount
171
   */
172
 
173
  if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
174
    rtems_set_errno_and_return_minus_one( EBUSY );
175
 
176
  /*
177
   * Allow the file system being unmounted on to do its cleanup.
178
   * If it fails it will set the errno to the approprate value
179
   * and the fileystem will not be modified.
180
   */
181
 
182
  if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
183
    return -1;
184
 
185
  /*
186
   *  Allow the mounted filesystem to unmark the use of the root node.
187
   *
188
   *  Run the unmount function for the subordinate file system.
189
   *
190
   *  If we fail to unmount the filesystem remount it on the base filesystems
191
   *  directory node.
192
   *
193
   *  NOTE:  Fatal error is called in a case which should never happen
194
   *         This was response was questionable but the best we could
195
   *         come up with.
196
   */
197
 
198
  if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
199
    if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
200
      rtems_fatal_error_occurred( 0 );
201
    return -1;
202
  }
203
 
204
  /*
205
   *  Extract the mount table entry from the chain
206
   */
207
 
208
  Chain_Extract( ( Chain_Node * ) mt_entry );
209
 
210
  /*
211
   *  Free the memory node that was allocated in mount
212
   *  Free the memory associated with the extracted mount table entry.
213
   */
214
 
215
  rtems_filesystem_freenode( fs_mount_loc );
216
  free( mt_entry );
217
 
218
  return 0;
219
}
220
 
221
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.