From 94b357c2b31be20b51784dc6f2ae837d58777cbd Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 5 Nov 1999 21:10:54 +0000 Subject: Unmount was failing as a side-effect of splitting the rmnod handler and not handling every case properly. --- cpukit/libfs/src/imfs/deviceio.c | 55 ++------------------ cpukit/libfs/src/imfs/imfs.h | 11 ++-- cpukit/libfs/src/imfs/imfs_eval.c | 2 +- cpukit/libfs/src/imfs/imfs_fsunmount.c | 7 ++- cpukit/libfs/src/imfs/imfs_handlers_device.c | 2 +- cpukit/libfs/src/imfs/imfs_rmnod.c | 77 ++++++++++++++++++++++++++++ cpukit/libfs/src/imfs/imfs_unlink.c | 11 ++-- 7 files changed, 102 insertions(+), 63 deletions(-) create mode 100644 cpukit/libfs/src/imfs/imfs_rmnod.c (limited to 'cpukit/libfs/src') diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c index 70b9706ada..fd969e7aa9 100644 --- a/cpukit/libfs/src/imfs/deviceio.c +++ b/cpukit/libfs/src/imfs/deviceio.c @@ -212,60 +212,11 @@ int device_lseek( /* * device_stat * - * This IMFS_stat() is used. + * The IMFS_stat() is used. */ /* * device_rmnod + * + * The IMFS_rmnod() is used. */ - -int device_rmnod( - rtems_filesystem_location_info_t *pathloc /* IN */ -) -{ - IMFS_jnode_t *the_jnode; - - the_jnode = (IMFS_jnode_t *) pathloc->node_access; - - /* - * Take the node out of the parent's chain that contains this node - */ - - if ( the_jnode->Parent != NULL ) { - Chain_Extract( (Chain_Node *) the_jnode ); - the_jnode->Parent = NULL; - } - - /* - * Decrement the link counter and see if we can free the space. - */ - - the_jnode->st_nlink--; - IMFS_update_ctime( the_jnode ); - - /* - * The file cannot be open and the link must be less than 1 to free. - */ - - if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) { - - /* - * Is the rtems_filesystem_current is this node? - */ - - if ( rtems_filesystem_current.node_access == pathloc->node_access ) - rtems_filesystem_current.node_access = NULL; - - /* - * Free memory associated with a memory file. - */ - - free( the_jnode ); - } - - return 0; - -} - - - diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index a88672c4b8..ff76bcd04b 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/libfs/src/imfs/imfs.h @@ -212,9 +212,10 @@ typedef enum { * Shared Data */ +extern rtems_filesystem_file_handlers_r IMFS_directory_handlers; extern rtems_filesystem_file_handlers_r IMFS_device_handlers; +extern rtems_filesystem_file_handlers_r IMFS_link_handlers; extern rtems_filesystem_file_handlers_r IMFS_memfile_handlers; -extern rtems_filesystem_file_handlers_r IMFS_directory_handlers; extern rtems_filesystem_operations_table IMFS_ops; extern rtems_filesystem_operations_table miniIMFS_ops; extern rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS; @@ -456,10 +457,6 @@ int device_lseek( int whence /* IN */ ); -int device_rmnod( - rtems_filesystem_location_info_t *pathloc /* IN */ -); - int IMFS_utime( rtems_filesystem_location_info_t *pathloc, /* IN */ time_t actime, /* IN */ @@ -492,6 +489,10 @@ int IMFS_fcntl( rtems_libio_t *iop ); +int IMFS_rmnod( + rtems_filesystem_location_info_t *pathloc /* IN */ +); + #ifdef __cplusplus } #endif diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c index ee488f1a19..66b5fa828c 100644 --- a/cpukit/libfs/src/imfs/imfs_eval.c +++ b/cpukit/libfs/src/imfs/imfs_eval.c @@ -45,7 +45,7 @@ int IMFS_Set_handlers( break; case IMFS_SYM_LINK: case IMFS_HARD_LINK: - loc->handlers = &rtems_filesystem_null_handlers; + loc->handlers = &IMFS_link_handlers; break; case IMFS_MEMORY_FILE: loc->handlers = fs_info->memfile_handlers; diff --git a/cpukit/libfs/src/imfs/imfs_fsunmount.c b/cpukit/libfs/src/imfs/imfs_fsunmount.c index 7a091c6fa3..9ca5f4c9fe 100644 --- a/cpukit/libfs/src/imfs/imfs_fsunmount.c +++ b/cpukit/libfs/src/imfs/imfs_fsunmount.c @@ -42,6 +42,11 @@ #define jnode_get_first_child( jnode ) \ ((IMFS_jnode_t *)( Chain_Head( jnode_get_control( jnode ) )->next)) +/* XXX should be in a more public place */ + +extern int IMFS_Set_handlers( + rtems_filesystem_location_info_t *loc +); int IMFS_fsunmount( rtems_filesystem_mount_table_entry_t *temp_mt_entry @@ -59,7 +64,6 @@ int IMFS_fsunmount( jnode = (IMFS_jnode_t *)temp_mt_entry->mt_fs_root.node_access; loc = temp_mt_entry->mt_fs_root; - /* * Set this to null to indicate that it is being unmounted. @@ -70,6 +74,7 @@ int IMFS_fsunmount( do { next = jnode->Parent; loc.node_access = (void *)jnode; + IMFS_Set_handlers( &loc ); if ( jnode->type != IMFS_DIRECTORY ) { result = IMFS_unlink( &loc ); diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c index 24b7ffa5bb..b6b9c808a0 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_device.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c @@ -34,5 +34,5 @@ rtems_filesystem_file_handlers_r IMFS_device_handlers = { NULL, /* fsync */ NULL, /* fdatasync */ NULL, /* fcntl */ - device_rmnod + IMFS_rmnod }; diff --git a/cpukit/libfs/src/imfs/imfs_rmnod.c b/cpukit/libfs/src/imfs/imfs_rmnod.c new file mode 100644 index 0000000000..4707722e86 --- /dev/null +++ b/cpukit/libfs/src/imfs/imfs_rmnod.c @@ -0,0 +1,77 @@ +/* + * IMFS Node Removal Handler + * + * This file contains the handler used to remove a node when a file type + * does not require special actions. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include "libio_.h" + +#include "imfs.h" + +/* + * IMFS_rmnod + */ + +int IMFS_rmnod( + rtems_filesystem_location_info_t *pathloc /* IN */ +) +{ + IMFS_jnode_t *the_jnode; + + the_jnode = (IMFS_jnode_t *) pathloc->node_access; + + /* + * Take the node out of the parent's chain that contains this node + */ + + if ( the_jnode->Parent != NULL ) { + Chain_Extract( (Chain_Node *) the_jnode ); + the_jnode->Parent = NULL; + } + + /* + * Decrement the link counter and see if we can free the space. + */ + + the_jnode->st_nlink--; + IMFS_update_ctime( the_jnode ); + + /* + * The file cannot be open and the link must be less than 1 to free. + */ + + if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) { + + /* + * Is the rtems_filesystem_current is this node? + */ + + if ( rtems_filesystem_current.node_access == pathloc->node_access ) + rtems_filesystem_current.node_access = NULL; + + /* + * Free memory associated with a memory file. + */ + + free( the_jnode ); + } + + return 0; + +} + + + diff --git a/cpukit/libfs/src/imfs/imfs_unlink.c b/cpukit/libfs/src/imfs/imfs_unlink.c index e138064e61..03938937f4 100644 --- a/cpukit/libfs/src/imfs/imfs_unlink.c +++ b/cpukit/libfs/src/imfs/imfs_unlink.c @@ -49,9 +49,10 @@ int IMFS_unlink( the_link.node_access = node->info.hard_link.link_node; /* - * If this is the last referance to the node - * Free the node that the link points to. + * If removing the last hard link to a node, then we need + * to remove the node that is a link and the node itself. */ + node->info.hard_link.link_node->st_nlink --; IMFS_update_ctime( node->info.hard_link.link_node ); if ( node->info.hard_link.link_node->st_nlink < 1) { @@ -61,7 +62,11 @@ int IMFS_unlink( } } - result = (*loc->handlers->rmnod)( &the_link ); + /* + * Now actually free the node we were asked to free. + */ + + result = (*loc->handlers->rmnod)( loc ); return result; } -- cgit v1.2.3