summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/unmount.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-23 11:39:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-29 12:25:34 +0200
commit847ad441cda2466680107b0b7607a8ceca3b17d4 (patch)
treed7ac7a11acd1c73faa39f250b54d08e96d21fedb /cpukit/libcsupport/src/unmount.c
parentshell/lsof: Use fprintf() instead of printk() (diff)
downloadrtems-847ad441cda2466680107b0b7607a8ceca3b17d4.tar.bz2
Filesystem: Wait for unmount() to finish
Diffstat (limited to 'cpukit/libcsupport/src/unmount.c')
-rw-r--r--cpukit/libcsupport/src/unmount.c49
1 files changed, 41 insertions, 8 deletions
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 <rtems/libio_.h>
+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;
}