summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2001-10-25 17:41:07 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2001-10-25 17:41:07 +0000
commit9c30d6a9a63cc278ff4ff5f67ee6206ee683591a (patch)
tree60bf2826bf117f656b5f3fed6f38ea4f5892691e /cpukit
parent1af79634798aca7004564d68bd47d3810a40370b (diff)
downloadrtems-9c30d6a9a63cc278ff4ff5f67ee6206ee683591a.tar.bz2
2001-10-25 Jennifer Averett <jennifer@OARcorp.com>
* libc/unmount.c: Primarily restructuring and clean up to address procedures which did not do what their name implied. Also addressed problem situation where unmount fails and the filesystem was inconsistent. The mounted filesystem could have been left hanging.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/libcsupport/src/unmount.c204
1 files changed, 116 insertions, 88 deletions
diff --git a/cpukit/libcsupport/src/unmount.c b/cpukit/libcsupport/src/unmount.c
index 81e097c818..fa5e71077d 100644
--- a/cpukit/libcsupport/src/unmount.c
+++ b/cpukit/libcsupport/src/unmount.c
@@ -42,12 +42,51 @@ int search_mt_for_mount_point(
rtems_filesystem_location_info_t *location_of_mount_point
);
+rtems_boolean rtems_filesystem_nodes_equal(
+ const rtems_filesystem_location_info_t *loc1,
+ const rtems_filesystem_location_info_t *loc2
+){
+ return ( loc1->node_access == loc2->node_access );
+}
+
+
+/*
+ * file_systems_below_this_mountpoint
+ *
+ * This routine will run through the entries that currently exist in the
+ * mount table chain. For each entry in the mount table chain it will
+ * compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
+ * mount table file system root nodes matches the new file system root node
+ * this indicates that we are trying to mount a file system that has already
+ * been mounted. This is not a permitted operation. temp_loc is set to
+ * the root node of the file system being unmounted.
+ */
-int file_systems_below_this_mountpoint(
+rtems_boolean file_systems_below_this_mountpoint(
const char *path,
- rtems_filesystem_location_info_t *temp_loc,
- rtems_filesystem_mount_table_entry_t *temp_mt_entry
-);
+ rtems_filesystem_location_info_t *fs_root_loc,
+ rtems_filesystem_mount_table_entry_t *fs_to_unmount
+)
+{
+ Chain_Node *the_node;
+ rtems_filesystem_mount_table_entry_t *the_mount_entry;
+
+ /*
+ * Search the mount table for any mount entries referencing this
+ * mount entry.
+ */
+
+ for ( the_node = rtems_filesystem_mount_table_control.first;
+ !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
+ the_node = the_node->next ) {
+ the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
+ if (the_mount_entry->mt_point_node.mt_entry == fs_root_loc->mt_entry ) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
/*
* unmount
@@ -61,132 +100,121 @@ int unmount(
const char *path
)
{
- int status;
- rtems_filesystem_location_info_t fs_root_loc;
- rtems_filesystem_mount_table_entry_t temp_mt_entry;
+ rtems_filesystem_location_info_t loc;
+ rtems_filesystem_location_info_t *fs_root_loc;
+ rtems_filesystem_location_info_t *fs_mount_loc;
+ rtems_filesystem_mount_table_entry_t *mt_entry;
/*
- * Are there any file systems below the path specified
+ * Get
+ * The root node of the mounted filesytem.
+ * The node for the directory that the fileystem is mounted on.
+ * The mount entry that is being refered to.
*/
- status = file_systems_below_this_mountpoint(
- path,
- &fs_root_loc,
- &temp_mt_entry
- );
-
- if ( status != 0 )
+ if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, TRUE ) )
return -1;
+ mt_entry = loc.mt_entry;
+ fs_mount_loc = &mt_entry->mt_point_node;
+ fs_root_loc = &mt_entry->mt_fs_root;
+
/*
- * Is the current node reference pointing to a node in the file system
- * we are attempting to unmount ?
+ * Verify this is the root node for the file system to be unmounted.
*/
- if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) {
- rtems_filesystem_freenode( &fs_root_loc );
- set_errno_and_return_minus_one( EBUSY );
+ if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
+ rtems_filesystem_freenode( &loc );
+ set_errno_and_return_minus_one( EACCES );
}
/*
- * Run the file descriptor table to determine if there are any file
- * descriptors that are currently active and reference nodes in the
- * file system that we are trying to unmount
+ * Free the loc node and just use the nodes from the mt_entry .
*/
- if ( rtems_libio_is_open_files_in_fs( fs_root_loc.mt_entry ) == 1 ) {
- rtems_filesystem_freenode( &fs_root_loc );
- set_errno_and_return_minus_one( EBUSY );
- }
-
+ rtems_filesystem_freenode( &loc );
+
/*
- * Allow the file system being unmounted on to do its cleanup.
+ * Verify Unmount is supported by both filesystems.
*/
- if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) {
- rtems_filesystem_freenode( &fs_root_loc );
- return -1;
- }
+ if ( !fs_mount_loc->ops->unmount_h )
+ set_errno_and_return_minus_one( ENOTSUP );
- /*
- * Run the unmount function for the subordinate file system.
- */
+ if ( !fs_root_loc->ops->fsunmount_me_h )
+ set_errno_and_return_minus_one( ENOTSUP );
- if ((temp_mt_entry.mt_fs_root.ops->fsunmount_me_h )( fs_root_loc.mt_entry ) != 0){
- rtems_filesystem_freenode( &fs_root_loc );
- return -1;
- }
/*
- * Extract the mount table entry from the chain
+ * Verify the current node is not in this filesystem.
+ * XXX - Joel I have a question here wasn't code added
+ * that made the current node thread based instead
+ * of system based? I thought it was but it doesn't
+ * look like it in this version.
*/
- Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry );
+ if ( rtems_filesystem_current.mt_entry == mt_entry )
+ set_errno_and_return_minus_one( EBUSY );
/*
- * Free the memory associated with the extracted mount table entry.
+ * Verify there are no file systems below the path specified
*/
- rtems_filesystem_freenode( &fs_root_loc.mt_entry->mt_point_node );
- free( fs_root_loc.mt_entry );
- rtems_filesystem_freenode( &fs_root_loc );
-
- return 0;
-}
+ if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
+ set_errno_and_return_minus_one( EBUSY );
+ /*
+ * Run the file descriptor table to determine if there are any file
+ * descriptors that are currently active and reference nodes in the
+ * file system that we are trying to unmount
+ */
-/*
- * file_systems_below_this_mountpoint
- *
- * This routine will run through the entries that currently exist in the
- * mount table chain. For each entry in the mount table chain it will
- * compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
- * mount table file system root nodes matches the new file system root node
- * this indicates that we are trying to mount a file system that has already
- * been mounted. This is not a permitted operation. temp_loc is set to
- * the root node of the file system being unmounted.
- */
+ if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
+ set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Allow the file system being unmounted on to do its cleanup.
+ * If it fails it will set the errno to the approprate value
+ * and the fileystem will not be modified.
+ */
-int file_systems_below_this_mountpoint(
- const char *path,
- rtems_filesystem_location_info_t *fs_root_loc,
- rtems_filesystem_mount_table_entry_t *fs_to_unmount
-)
-{
- Chain_Node *the_node;
- rtems_filesystem_mount_table_entry_t *the_mount_entry;
+ if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
+ return -1;
/*
- * Is the path even a valid node name in the existing tree?
+ * Allow the mounted filesystem to unmark the use of the root node.
+ *
+ * Run the unmount function for the subordinate file system.
+ *
+ * If we fail to unmount the filesystem remount it on the base filesystems
+ * directory node.
+ *
+ * NOTE: Fatal error is called in a case which should never happen
+ * This was response was questionable but the best we could
+ * come up with.
*/
- if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) )
+ if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
+ if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
+ rtems_fatal_error_occurred( 0 );
return -1;
-
+ }
+
/*
- * Verify this is the root node for the file system to be unmounted.
+ * Extract the mount table entry from the chain
*/
- *fs_to_unmount = *fs_root_loc->mt_entry;
- if ( fs_to_unmount->mt_fs_root.node_access != fs_root_loc->node_access ){
- rtems_filesystem_freenode(fs_root_loc);
- set_errno_and_return_minus_one( EACCES );
- }
+ Chain_Extract( ( Chain_Node * ) mt_entry );
/*
- * Search the mount table for any mount entries referencing this
- * mount entry.
+ * Free the memory node that was allocated in mount
+ * Free the memory associated with the extracted mount table entry.
*/
- for ( the_node = rtems_filesystem_mount_table_control.first;
- !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
- the_node = the_node->next ) {
- the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
- if (the_mount_entry->mt_point_node.mt_entry == fs_root_loc->mt_entry ) {
- rtems_filesystem_freenode(fs_root_loc);
- set_errno_and_return_minus_one( EBUSY );
- }
- }
+ rtems_filesystem_freenode( fs_mount_loc );
+ free( mt_entry );
return 0;
}
+
+