From 847ad441cda2466680107b0b7607a8ceca3b17d4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 23 May 2012 11:39:50 +0200 Subject: Filesystem: Wait for unmount() to finish --- cpukit/libcsupport/src/unmount.c | 49 +++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'cpukit/libcsupport/src/unmount.c') diff --git a/cpukit/libcsupport/src/unmount.c b/cpukit/libcsupport/src/unmount.c index b58955d33c..ad45220fd5 100644 --- a/cpukit/libcsupport/src/unmount.c +++ b/cpukit/libcsupport/src/unmount.c @@ -22,6 +22,18 @@ #include +static bool contains_root_or_current_directory( + const rtems_filesystem_mount_table_entry_t *mt_entry +) +{ + const rtems_filesystem_location_info_t *root = + &rtems_filesystem_root->location; + const rtems_filesystem_location_info_t *current = + &rtems_filesystem_current->location; + + return mt_entry == root->mt_entry || mt_entry == current->mt_entry; +} + int unmount( const char *path ) { int rv = 0; @@ -32,16 +44,23 @@ int unmount( const char *path ) rtems_filesystem_mount_table_entry_t *mt_entry = currentloc->mt_entry; if ( rtems_filesystem_location_is_root( currentloc ) ) { - const rtems_filesystem_operations_table *mt_point_ops = - mt_entry->mt_point_node->location.mt_entry->ops; + if ( !contains_root_or_current_directory( mt_entry ) ) { + const rtems_filesystem_operations_table *mt_point_ops = + mt_entry->mt_point_node->location.mt_entry->ops; - rv = (*mt_point_ops->unmount_h)( mt_entry ); - if ( rv == 0 ) { - rtems_filesystem_mt_entry_declare_lock_context( lock_context ); + rv = (*mt_point_ops->unmount_h)( mt_entry ); + if ( rv == 0 ) { + rtems_id self_task_id = rtems_task_self(); + rtems_filesystem_mt_entry_declare_lock_context( lock_context ); - rtems_filesystem_mt_entry_lock( lock_context ); - mt_entry->mounted = false; - rtems_filesystem_mt_entry_unlock( lock_context ); + rtems_filesystem_mt_entry_lock( lock_context ); + mt_entry->unmount_task = self_task_id; + mt_entry->mounted = false; + rtems_filesystem_mt_entry_unlock( lock_context ); + } + } else { + errno = EBUSY; + rv = -1; } } else { errno = EACCES; @@ -50,5 +69,19 @@ int unmount( const char *path ) rtems_filesystem_eval_path_cleanup( &ctx ); + if ( rv == 0 ) { + rtems_event_set out; + rtems_status_code sc = rtems_event_receive( + RTEMS_FILESYSTEM_UNMOUNT_EVENT, + RTEMS_EVENT_ALL | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &out + ); + + if ( sc != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred( 0xdeadbeef ); + } + } + return rv; } -- cgit v1.2.3