diff --git a/c/src/exec/libcsupport/src/unmount.c b/c/src/exec/libcsupport/src/unmount.c index 81e097c818..fa5e71077d 100644 --- a/c/src/exec/libcsupport/src/unmount.c +++ b/c/src/exec/libcsupport/src/unmount.c @@ -42,96 +42,11 @@ int search_mt_for_mount_point( rtems_filesystem_location_info_t *location_of_mount_point ); - -int file_systems_below_this_mountpoint( - const char *path, - rtems_filesystem_location_info_t *temp_loc, - rtems_filesystem_mount_table_entry_t *temp_mt_entry -); - -/* - * unmount - * - * This routine will attempt to unmount the file system that has been - * is mounted a path. If the operation is successful, 0 will - * be returned to the calling routine. Otherwise, 1 will be returned. - */ - -int unmount( - const char *path -) -{ - int status; - rtems_filesystem_location_info_t fs_root_loc; - rtems_filesystem_mount_table_entry_t temp_mt_entry; - - /* - * Are there any file systems below the path specified - */ - - status = file_systems_below_this_mountpoint( - path, - &fs_root_loc, - &temp_mt_entry - ); - - if ( status != 0 ) - return -1; - - /* - * Is the current node reference pointing to a node in the file system - * we are attempting to unmount ? - */ - - if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) { - rtems_filesystem_freenode( &fs_root_loc ); - 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 - */ - - 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 ); - } - - /* - * Allow the file system being unmounted on to do its cleanup. - */ - - if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) { - rtems_filesystem_freenode( &fs_root_loc ); - return -1; - } - - /* - * Run the unmount function for the subordinate file system. - */ - - 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 - */ - - Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry ); - - /* - * Free the memory associated with the extracted mount table entry. - */ - - 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; +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 ); } @@ -147,7 +62,7 @@ int unmount( * 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 *fs_root_loc, rtems_filesystem_mount_table_entry_t *fs_to_unmount @@ -156,23 +71,6 @@ int file_systems_below_this_mountpoint( Chain_Node *the_node; rtems_filesystem_mount_table_entry_t *the_mount_entry; - /* - * Is the path even a valid node name in the existing tree? - */ - - if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) ) - return -1; - - /* - * Verify this is the root node for the file system to be unmounted. - */ - - *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 ); - } - /* * Search the mount table for any mount entries referencing this * mount entry. @@ -183,10 +81,140 @@ int file_systems_below_this_mountpoint( 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 ); + return TRUE; } } + return FALSE; +} + +/* + * unmount + * + * This routine will attempt to unmount the file system that has been + * is mounted a path. If the operation is successful, 0 will + * be returned to the calling routine. Otherwise, 1 will be returned. + */ + +int unmount( + const char *path +) +{ + 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; + + /* + * 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. + */ + + 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; + + /* + * Verify this is the root node for the file system to be unmounted. + */ + + if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){ + rtems_filesystem_freenode( &loc ); + set_errno_and_return_minus_one( EACCES ); + } + + /* + * Free the loc node and just use the nodes from the mt_entry . + */ + + rtems_filesystem_freenode( &loc ); + + /* + * Verify Unmount is supported by both filesystems. + */ + + if ( !fs_mount_loc->ops->unmount_h ) + set_errno_and_return_minus_one( ENOTSUP ); + + if ( !fs_root_loc->ops->fsunmount_me_h ) + set_errno_and_return_minus_one( ENOTSUP ); + + + /* + * 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. + */ + + if ( rtems_filesystem_current.mt_entry == mt_entry ) + set_errno_and_return_minus_one( EBUSY ); + + /* + * Verify there are no file systems below the path specified + */ + + 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 + */ + + 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. + */ + + if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 ) + return -1; + + /* + * 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 ((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; + } + + /* + * Extract the mount table entry from the chain + */ + + Chain_Extract( ( Chain_Node * ) mt_entry ); + + /* + * Free the memory node that was allocated in mount + * Free the memory associated with the extracted mount table entry. + */ + + rtems_filesystem_freenode( fs_mount_loc ); + free( mt_entry ); + return 0; } + + diff --git a/c/src/lib/ChangeLog b/c/src/lib/ChangeLog index 57d5ae4f85..6ebb95d5f5 100644 --- a/c/src/lib/ChangeLog +++ b/c/src/lib/ChangeLog @@ -1,3 +1,10 @@ +2001-10-25 Jennifer Averett + + * 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. + 2001-10-25 Jennifer Averett * libc/libio.c: Initialize more fields to NULL/0 during initialiation. diff --git a/c/src/lib/libc/unmount.c b/c/src/lib/libc/unmount.c index 81e097c818..fa5e71077d 100644 --- a/c/src/lib/libc/unmount.c +++ b/c/src/lib/libc/unmount.c @@ -42,96 +42,11 @@ int search_mt_for_mount_point( rtems_filesystem_location_info_t *location_of_mount_point ); - -int file_systems_below_this_mountpoint( - const char *path, - rtems_filesystem_location_info_t *temp_loc, - rtems_filesystem_mount_table_entry_t *temp_mt_entry -); - -/* - * unmount - * - * This routine will attempt to unmount the file system that has been - * is mounted a path. If the operation is successful, 0 will - * be returned to the calling routine. Otherwise, 1 will be returned. - */ - -int unmount( - const char *path -) -{ - int status; - rtems_filesystem_location_info_t fs_root_loc; - rtems_filesystem_mount_table_entry_t temp_mt_entry; - - /* - * Are there any file systems below the path specified - */ - - status = file_systems_below_this_mountpoint( - path, - &fs_root_loc, - &temp_mt_entry - ); - - if ( status != 0 ) - return -1; - - /* - * Is the current node reference pointing to a node in the file system - * we are attempting to unmount ? - */ - - if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) { - rtems_filesystem_freenode( &fs_root_loc ); - 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 - */ - - 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 ); - } - - /* - * Allow the file system being unmounted on to do its cleanup. - */ - - if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) { - rtems_filesystem_freenode( &fs_root_loc ); - return -1; - } - - /* - * Run the unmount function for the subordinate file system. - */ - - 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 - */ - - Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry ); - - /* - * Free the memory associated with the extracted mount table entry. - */ - - 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; +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 ); } @@ -147,7 +62,7 @@ int unmount( * 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 *fs_root_loc, rtems_filesystem_mount_table_entry_t *fs_to_unmount @@ -156,23 +71,6 @@ int file_systems_below_this_mountpoint( Chain_Node *the_node; rtems_filesystem_mount_table_entry_t *the_mount_entry; - /* - * Is the path even a valid node name in the existing tree? - */ - - if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) ) - return -1; - - /* - * Verify this is the root node for the file system to be unmounted. - */ - - *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 ); - } - /* * Search the mount table for any mount entries referencing this * mount entry. @@ -183,10 +81,140 @@ int file_systems_below_this_mountpoint( 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 ); + return TRUE; } } + return FALSE; +} + +/* + * unmount + * + * This routine will attempt to unmount the file system that has been + * is mounted a path. If the operation is successful, 0 will + * be returned to the calling routine. Otherwise, 1 will be returned. + */ + +int unmount( + const char *path +) +{ + 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; + + /* + * 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. + */ + + 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; + + /* + * Verify this is the root node for the file system to be unmounted. + */ + + if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){ + rtems_filesystem_freenode( &loc ); + set_errno_and_return_minus_one( EACCES ); + } + + /* + * Free the loc node and just use the nodes from the mt_entry . + */ + + rtems_filesystem_freenode( &loc ); + + /* + * Verify Unmount is supported by both filesystems. + */ + + if ( !fs_mount_loc->ops->unmount_h ) + set_errno_and_return_minus_one( ENOTSUP ); + + if ( !fs_root_loc->ops->fsunmount_me_h ) + set_errno_and_return_minus_one( ENOTSUP ); + + + /* + * 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. + */ + + if ( rtems_filesystem_current.mt_entry == mt_entry ) + set_errno_and_return_minus_one( EBUSY ); + + /* + * Verify there are no file systems below the path specified + */ + + 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 + */ + + 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. + */ + + if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 ) + return -1; + + /* + * 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 ((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; + } + + /* + * Extract the mount table entry from the chain + */ + + Chain_Extract( ( Chain_Node * ) mt_entry ); + + /* + * Free the memory node that was allocated in mount + * Free the memory associated with the extracted mount table entry. + */ + + rtems_filesystem_freenode( fs_mount_loc ); + free( mt_entry ); + return 0; } + + 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,96 +42,11 @@ int search_mt_for_mount_point( rtems_filesystem_location_info_t *location_of_mount_point ); - -int file_systems_below_this_mountpoint( - const char *path, - rtems_filesystem_location_info_t *temp_loc, - rtems_filesystem_mount_table_entry_t *temp_mt_entry -); - -/* - * unmount - * - * This routine will attempt to unmount the file system that has been - * is mounted a path. If the operation is successful, 0 will - * be returned to the calling routine. Otherwise, 1 will be returned. - */ - -int unmount( - const char *path -) -{ - int status; - rtems_filesystem_location_info_t fs_root_loc; - rtems_filesystem_mount_table_entry_t temp_mt_entry; - - /* - * Are there any file systems below the path specified - */ - - status = file_systems_below_this_mountpoint( - path, - &fs_root_loc, - &temp_mt_entry - ); - - if ( status != 0 ) - return -1; - - /* - * Is the current node reference pointing to a node in the file system - * we are attempting to unmount ? - */ - - if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) { - rtems_filesystem_freenode( &fs_root_loc ); - 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 - */ - - 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 ); - } - - /* - * Allow the file system being unmounted on to do its cleanup. - */ - - if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) { - rtems_filesystem_freenode( &fs_root_loc ); - return -1; - } - - /* - * Run the unmount function for the subordinate file system. - */ - - 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 - */ - - Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry ); - - /* - * Free the memory associated with the extracted mount table entry. - */ - - 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; +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 ); } @@ -147,7 +62,7 @@ int unmount( * 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 *fs_root_loc, rtems_filesystem_mount_table_entry_t *fs_to_unmount @@ -156,23 +71,6 @@ int file_systems_below_this_mountpoint( Chain_Node *the_node; rtems_filesystem_mount_table_entry_t *the_mount_entry; - /* - * Is the path even a valid node name in the existing tree? - */ - - if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) ) - return -1; - - /* - * Verify this is the root node for the file system to be unmounted. - */ - - *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 ); - } - /* * Search the mount table for any mount entries referencing this * mount entry. @@ -183,10 +81,140 @@ int file_systems_below_this_mountpoint( 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 ); + return TRUE; } } + return FALSE; +} + +/* + * unmount + * + * This routine will attempt to unmount the file system that has been + * is mounted a path. If the operation is successful, 0 will + * be returned to the calling routine. Otherwise, 1 will be returned. + */ + +int unmount( + const char *path +) +{ + 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; + + /* + * 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. + */ + + 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; + + /* + * Verify this is the root node for the file system to be unmounted. + */ + + if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){ + rtems_filesystem_freenode( &loc ); + set_errno_and_return_minus_one( EACCES ); + } + + /* + * Free the loc node and just use the nodes from the mt_entry . + */ + + rtems_filesystem_freenode( &loc ); + + /* + * Verify Unmount is supported by both filesystems. + */ + + if ( !fs_mount_loc->ops->unmount_h ) + set_errno_and_return_minus_one( ENOTSUP ); + + if ( !fs_root_loc->ops->fsunmount_me_h ) + set_errno_and_return_minus_one( ENOTSUP ); + + + /* + * 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. + */ + + if ( rtems_filesystem_current.mt_entry == mt_entry ) + set_errno_and_return_minus_one( EBUSY ); + + /* + * Verify there are no file systems below the path specified + */ + + 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 + */ + + 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. + */ + + if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 ) + return -1; + + /* + * 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 ((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; + } + + /* + * Extract the mount table entry from the chain + */ + + Chain_Extract( ( Chain_Node * ) mt_entry ); + + /* + * Free the memory node that was allocated in mount + * Free the memory associated with the extracted mount table entry. + */ + + rtems_filesystem_freenode( fs_mount_loc ); + free( mt_entry ); + return 0; } + +