Changeset 9c30d6a9 in rtems


Ignore:
Timestamp:
Oct 25, 2001, 5:41:07 PM (19 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
859c7d8
Parents:
1af79634
Message:

2001-10-25 Jennifer Averett <jennifer@…>

  • 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.
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/libcsupport/src/unmount.c

    r1af79634 r9c30d6a9  
    4343);
    4444
    45 
    46 int file_systems_below_this_mountpoint(
    47   const char                            *path,
    48   rtems_filesystem_location_info_t      *temp_loc,
    49   rtems_filesystem_mount_table_entry_t  *temp_mt_entry
    50 );
    51 
    52 /*
    53  *  unmount
    54  *
    55  *  This routine will attempt to unmount the file system that has been
    56  *  is mounted a path.  If the operation is successful, 0 will
    57  *  be returned to the calling routine.  Otherwise, 1 will be returned.
    58  */
    59 
    60 int unmount(
    61   const char *path
    62 )
    63 {
    64   int                                   status;
    65   rtems_filesystem_location_info_t      fs_root_loc;
    66   rtems_filesystem_mount_table_entry_t  temp_mt_entry;
    67 
    68   /*
    69    *  Are there any file systems below the path specified
    70    */
    71 
    72   status = file_systems_below_this_mountpoint(
    73     path,
    74     &fs_root_loc,
    75     &temp_mt_entry
    76   );
    77 
    78   if ( status != 0 )
    79     return -1;
    80 
    81   /*
    82    *  Is the current node reference pointing to a node in the file system
    83    *  we are attempting to unmount ?
    84    */
    85 
    86   if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) {
    87     rtems_filesystem_freenode( &fs_root_loc );
    88     set_errno_and_return_minus_one( EBUSY );
    89   }
    90 
    91   /*
    92    *  Run the file descriptor table to determine if there are any file
    93    *  descriptors that are currently active and reference nodes in the
    94    *  file system that we are trying to unmount
    95    */
    96 
    97   if ( rtems_libio_is_open_files_in_fs( fs_root_loc.mt_entry ) == 1 ) {
    98     rtems_filesystem_freenode( &fs_root_loc );
    99     set_errno_and_return_minus_one( EBUSY );
    100   }
    101  
    102   /*
    103    * Allow the file system being unmounted on to do its cleanup.
    104    */
    105 
    106   if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) {
    107     rtems_filesystem_freenode( &fs_root_loc );
    108     return -1;
    109   }
    110 
    111   /*
    112    * Run the unmount function for the subordinate file system.
    113    */
    114 
    115   if ((temp_mt_entry.mt_fs_root.ops->fsunmount_me_h )( fs_root_loc.mt_entry ) != 0){
    116     rtems_filesystem_freenode( &fs_root_loc );
    117     return -1;
    118   }
    119 
    120   /*
    121    *  Extract the mount table entry from the chain
    122    */
    123 
    124   Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry );
    125 
    126   /*
    127    *  Free the memory associated with the extracted mount table entry.
    128    */
    129 
    130   rtems_filesystem_freenode( &fs_root_loc.mt_entry->mt_point_node );
    131   free( fs_root_loc.mt_entry );
    132   rtems_filesystem_freenode( &fs_root_loc );
    133 
    134   return 0;
     45rtems_boolean rtems_filesystem_nodes_equal(
     46  const rtems_filesystem_location_info_t   *loc1,
     47  const rtems_filesystem_location_info_t   *loc2
     48){
     49  return ( loc1->node_access == loc2->node_access );
    13550}
    13651
     
    14863 */
    14964
    150 int file_systems_below_this_mountpoint(
     65rtems_boolean file_systems_below_this_mountpoint(
    15166  const char                            *path,
    15267  rtems_filesystem_location_info_t      *fs_root_loc,
     
    15873
    15974  /*
    160    *  Is the path even a valid node name in the existing tree?
    161    */
    162 
    163   if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) )
    164     return -1;
    165  
    166   /*
    167    * Verify this is the root node for the file system to be unmounted.
    168    */
    169 
    170   *fs_to_unmount = *fs_root_loc->mt_entry;
    171   if ( fs_to_unmount->mt_fs_root.node_access != fs_root_loc->node_access ){
    172     rtems_filesystem_freenode(fs_root_loc);
    173     set_errno_and_return_minus_one( EACCES );
    174   }
    175 
    176   /*
    17775   * Search the mount table for any mount entries referencing this
    17876   * mount entry.
     
    18482     the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
    18583     if (the_mount_entry->mt_point_node.mt_entry  == fs_root_loc->mt_entry ) {
    186         rtems_filesystem_freenode(fs_root_loc); 
    187         set_errno_and_return_minus_one( EBUSY );
     84        return TRUE;
    18885     }
    18986  }
    19087
     88  return FALSE;
     89}
     90
     91/*
     92 *  unmount
     93 *
     94 *  This routine will attempt to unmount the file system that has been
     95 *  is mounted a path.  If the operation is successful, 0 will
     96 *  be returned to the calling routine.  Otherwise, 1 will be returned.
     97 */
     98
     99int unmount(
     100  const char *path
     101)
     102{
     103  rtems_filesystem_location_info_t      loc;
     104  rtems_filesystem_location_info_t     *fs_root_loc;
     105  rtems_filesystem_location_info_t     *fs_mount_loc;
     106  rtems_filesystem_mount_table_entry_t *mt_entry;
     107
     108  /*
     109   *  Get
     110   *    The root node of the mounted filesytem.
     111   *    The node for the directory that the fileystem is mounted on.
     112   *    The mount entry that is being refered to.
     113   */
     114
     115  if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, TRUE ) )
     116    return -1;
     117
     118  mt_entry     = loc.mt_entry;
     119  fs_mount_loc = &mt_entry->mt_point_node;
     120  fs_root_loc  = &mt_entry->mt_fs_root;
     121       
     122  /*
     123   * Verify this is the root node for the file system to be unmounted.
     124   */
     125
     126  if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
     127    rtems_filesystem_freenode( &loc );
     128    set_errno_and_return_minus_one( EACCES );
     129  }
     130
     131  /*
     132   * Free the loc node and just use the nodes from the mt_entry .
     133   */
     134
     135  rtems_filesystem_freenode( &loc );
     136
     137  /*
     138   * Verify Unmount is supported by both filesystems.
     139   */
     140
     141  if ( !fs_mount_loc->ops->unmount_h )
     142    set_errno_and_return_minus_one( ENOTSUP );
     143
     144  if ( !fs_root_loc->ops->fsunmount_me_h )
     145    set_errno_and_return_minus_one( ENOTSUP );
     146
     147
     148  /*
     149   *  Verify the current node is not in this filesystem.
     150   *  XXX - Joel I have a question here wasn't code added
     151   *        that made the current node thread based instead
     152   *        of system based?  I thought it was but it doesn't
     153   *        look like it in this version.
     154   */
     155
     156  if ( rtems_filesystem_current.mt_entry == mt_entry )
     157    set_errno_and_return_minus_one( EBUSY );
     158
     159  /*
     160   *  Verify there are no file systems below the path specified
     161   */
     162
     163  if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
     164    set_errno_and_return_minus_one( EBUSY );
     165
     166  /*
     167   *  Run the file descriptor table to determine if there are any file
     168   *  descriptors that are currently active and reference nodes in the
     169   *  file system that we are trying to unmount
     170   */
     171
     172  if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
     173    set_errno_and_return_minus_one( EBUSY );
     174 
     175  /*
     176   * Allow the file system being unmounted on to do its cleanup.
     177   * If it fails it will set the errno to the approprate value
     178   * and the fileystem will not be modified.
     179   */
     180
     181  if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
     182    return -1;
     183
     184  /*
     185   *  Allow the mounted filesystem to unmark the use of the root node.
     186   *
     187   *  Run the unmount function for the subordinate file system.
     188   *
     189   *  If we fail to unmount the filesystem remount it on the base filesystems
     190   *  directory node.
     191   *
     192   *  NOTE:  Fatal error is called in a case which should never happen
     193   *         This was response was questionable but the best we could
     194   *         come up with.
     195   */
     196
     197  if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
     198    if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
     199      rtems_fatal_error_occurred( 0 );
     200    return -1;
     201  }
     202
     203  /*
     204   *  Extract the mount table entry from the chain
     205   */
     206
     207  Chain_Extract( ( Chain_Node * ) mt_entry );
     208
     209  /*
     210   *  Free the memory node that was allocated in mount
     211   *  Free the memory associated with the extracted mount table entry.
     212   */
     213
     214  rtems_filesystem_freenode( fs_mount_loc );
     215  free( mt_entry );
     216
    191217  return 0;
    192218}
     219
     220
  • c/src/lib/ChangeLog

    r1af79634 r9c30d6a9  
     12001-10-25      Jennifer Averett <jennifer@OARcorp.com>
     2
     3        * libc/unmount.c: Primarily restructuring and clean up to address
     4        procedures which did not do what their name implied.  Also addressed
     5        problem situation where unmount fails and the filesystem was
     6        inconsistent.  The mounted filesystem could have been left hanging.
     7
    182001-10-25      Jennifer Averett <jennifer@OARcorp.com>
    29
  • c/src/lib/libc/unmount.c

    r1af79634 r9c30d6a9  
    4343);
    4444
    45 
    46 int file_systems_below_this_mountpoint(
    47   const char                            *path,
    48   rtems_filesystem_location_info_t      *temp_loc,
    49   rtems_filesystem_mount_table_entry_t  *temp_mt_entry
    50 );
    51 
    52 /*
    53  *  unmount
    54  *
    55  *  This routine will attempt to unmount the file system that has been
    56  *  is mounted a path.  If the operation is successful, 0 will
    57  *  be returned to the calling routine.  Otherwise, 1 will be returned.
    58  */
    59 
    60 int unmount(
    61   const char *path
    62 )
    63 {
    64   int                                   status;
    65   rtems_filesystem_location_info_t      fs_root_loc;
    66   rtems_filesystem_mount_table_entry_t  temp_mt_entry;
    67 
    68   /*
    69    *  Are there any file systems below the path specified
    70    */
    71 
    72   status = file_systems_below_this_mountpoint(
    73     path,
    74     &fs_root_loc,
    75     &temp_mt_entry
    76   );
    77 
    78   if ( status != 0 )
    79     return -1;
    80 
    81   /*
    82    *  Is the current node reference pointing to a node in the file system
    83    *  we are attempting to unmount ?
    84    */
    85 
    86   if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) {
    87     rtems_filesystem_freenode( &fs_root_loc );
    88     set_errno_and_return_minus_one( EBUSY );
    89   }
    90 
    91   /*
    92    *  Run the file descriptor table to determine if there are any file
    93    *  descriptors that are currently active and reference nodes in the
    94    *  file system that we are trying to unmount
    95    */
    96 
    97   if ( rtems_libio_is_open_files_in_fs( fs_root_loc.mt_entry ) == 1 ) {
    98     rtems_filesystem_freenode( &fs_root_loc );
    99     set_errno_and_return_minus_one( EBUSY );
    100   }
    101  
    102   /*
    103    * Allow the file system being unmounted on to do its cleanup.
    104    */
    105 
    106   if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) {
    107     rtems_filesystem_freenode( &fs_root_loc );
    108     return -1;
    109   }
    110 
    111   /*
    112    * Run the unmount function for the subordinate file system.
    113    */
    114 
    115   if ((temp_mt_entry.mt_fs_root.ops->fsunmount_me_h )( fs_root_loc.mt_entry ) != 0){
    116     rtems_filesystem_freenode( &fs_root_loc );
    117     return -1;
    118   }
    119 
    120   /*
    121    *  Extract the mount table entry from the chain
    122    */
    123 
    124   Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry );
    125 
    126   /*
    127    *  Free the memory associated with the extracted mount table entry.
    128    */
    129 
    130   rtems_filesystem_freenode( &fs_root_loc.mt_entry->mt_point_node );
    131   free( fs_root_loc.mt_entry );
    132   rtems_filesystem_freenode( &fs_root_loc );
    133 
    134   return 0;
     45rtems_boolean rtems_filesystem_nodes_equal(
     46  const rtems_filesystem_location_info_t   *loc1,
     47  const rtems_filesystem_location_info_t   *loc2
     48){
     49  return ( loc1->node_access == loc2->node_access );
    13550}
    13651
     
    14863 */
    14964
    150 int file_systems_below_this_mountpoint(
     65rtems_boolean file_systems_below_this_mountpoint(
    15166  const char                            *path,
    15267  rtems_filesystem_location_info_t      *fs_root_loc,
     
    15873
    15974  /*
    160    *  Is the path even a valid node name in the existing tree?
    161    */
    162 
    163   if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) )
    164     return -1;
    165  
    166   /*
    167    * Verify this is the root node for the file system to be unmounted.
    168    */
    169 
    170   *fs_to_unmount = *fs_root_loc->mt_entry;
    171   if ( fs_to_unmount->mt_fs_root.node_access != fs_root_loc->node_access ){
    172     rtems_filesystem_freenode(fs_root_loc);
    173     set_errno_and_return_minus_one( EACCES );
    174   }
    175 
    176   /*
    17775   * Search the mount table for any mount entries referencing this
    17876   * mount entry.
     
    18482     the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
    18583     if (the_mount_entry->mt_point_node.mt_entry  == fs_root_loc->mt_entry ) {
    186         rtems_filesystem_freenode(fs_root_loc); 
    187         set_errno_and_return_minus_one( EBUSY );
     84        return TRUE;
    18885     }
    18986  }
    19087
     88  return FALSE;
     89}
     90
     91/*
     92 *  unmount
     93 *
     94 *  This routine will attempt to unmount the file system that has been
     95 *  is mounted a path.  If the operation is successful, 0 will
     96 *  be returned to the calling routine.  Otherwise, 1 will be returned.
     97 */
     98
     99int unmount(
     100  const char *path
     101)
     102{
     103  rtems_filesystem_location_info_t      loc;
     104  rtems_filesystem_location_info_t     *fs_root_loc;
     105  rtems_filesystem_location_info_t     *fs_mount_loc;
     106  rtems_filesystem_mount_table_entry_t *mt_entry;
     107
     108  /*
     109   *  Get
     110   *    The root node of the mounted filesytem.
     111   *    The node for the directory that the fileystem is mounted on.
     112   *    The mount entry that is being refered to.
     113   */
     114
     115  if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, TRUE ) )
     116    return -1;
     117
     118  mt_entry     = loc.mt_entry;
     119  fs_mount_loc = &mt_entry->mt_point_node;
     120  fs_root_loc  = &mt_entry->mt_fs_root;
     121       
     122  /*
     123   * Verify this is the root node for the file system to be unmounted.
     124   */
     125
     126  if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
     127    rtems_filesystem_freenode( &loc );
     128    set_errno_and_return_minus_one( EACCES );
     129  }
     130
     131  /*
     132   * Free the loc node and just use the nodes from the mt_entry .
     133   */
     134
     135  rtems_filesystem_freenode( &loc );
     136
     137  /*
     138   * Verify Unmount is supported by both filesystems.
     139   */
     140
     141  if ( !fs_mount_loc->ops->unmount_h )
     142    set_errno_and_return_minus_one( ENOTSUP );
     143
     144  if ( !fs_root_loc->ops->fsunmount_me_h )
     145    set_errno_and_return_minus_one( ENOTSUP );
     146
     147
     148  /*
     149   *  Verify the current node is not in this filesystem.
     150   *  XXX - Joel I have a question here wasn't code added
     151   *        that made the current node thread based instead
     152   *        of system based?  I thought it was but it doesn't
     153   *        look like it in this version.
     154   */
     155
     156  if ( rtems_filesystem_current.mt_entry == mt_entry )
     157    set_errno_and_return_minus_one( EBUSY );
     158
     159  /*
     160   *  Verify there are no file systems below the path specified
     161   */
     162
     163  if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
     164    set_errno_and_return_minus_one( EBUSY );
     165
     166  /*
     167   *  Run the file descriptor table to determine if there are any file
     168   *  descriptors that are currently active and reference nodes in the
     169   *  file system that we are trying to unmount
     170   */
     171
     172  if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
     173    set_errno_and_return_minus_one( EBUSY );
     174 
     175  /*
     176   * Allow the file system being unmounted on to do its cleanup.
     177   * If it fails it will set the errno to the approprate value
     178   * and the fileystem will not be modified.
     179   */
     180
     181  if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
     182    return -1;
     183
     184  /*
     185   *  Allow the mounted filesystem to unmark the use of the root node.
     186   *
     187   *  Run the unmount function for the subordinate file system.
     188   *
     189   *  If we fail to unmount the filesystem remount it on the base filesystems
     190   *  directory node.
     191   *
     192   *  NOTE:  Fatal error is called in a case which should never happen
     193   *         This was response was questionable but the best we could
     194   *         come up with.
     195   */
     196
     197  if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
     198    if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
     199      rtems_fatal_error_occurred( 0 );
     200    return -1;
     201  }
     202
     203  /*
     204   *  Extract the mount table entry from the chain
     205   */
     206
     207  Chain_Extract( ( Chain_Node * ) mt_entry );
     208
     209  /*
     210   *  Free the memory node that was allocated in mount
     211   *  Free the memory associated with the extracted mount table entry.
     212   */
     213
     214  rtems_filesystem_freenode( fs_mount_loc );
     215  free( mt_entry );
     216
    191217  return 0;
    192218}
     219
     220
  • cpukit/libcsupport/src/unmount.c

    r1af79634 r9c30d6a9  
    4343);
    4444
    45 
    46 int file_systems_below_this_mountpoint(
    47   const char                            *path,
    48   rtems_filesystem_location_info_t      *temp_loc,
    49   rtems_filesystem_mount_table_entry_t  *temp_mt_entry
    50 );
    51 
    52 /*
    53  *  unmount
    54  *
    55  *  This routine will attempt to unmount the file system that has been
    56  *  is mounted a path.  If the operation is successful, 0 will
    57  *  be returned to the calling routine.  Otherwise, 1 will be returned.
    58  */
    59 
    60 int unmount(
    61   const char *path
    62 )
    63 {
    64   int                                   status;
    65   rtems_filesystem_location_info_t      fs_root_loc;
    66   rtems_filesystem_mount_table_entry_t  temp_mt_entry;
    67 
    68   /*
    69    *  Are there any file systems below the path specified
    70    */
    71 
    72   status = file_systems_below_this_mountpoint(
    73     path,
    74     &fs_root_loc,
    75     &temp_mt_entry
    76   );
    77 
    78   if ( status != 0 )
    79     return -1;
    80 
    81   /*
    82    *  Is the current node reference pointing to a node in the file system
    83    *  we are attempting to unmount ?
    84    */
    85 
    86   if ( rtems_filesystem_current.mt_entry == fs_root_loc.mt_entry ) {
    87     rtems_filesystem_freenode( &fs_root_loc );
    88     set_errno_and_return_minus_one( EBUSY );
    89   }
    90 
    91   /*
    92    *  Run the file descriptor table to determine if there are any file
    93    *  descriptors that are currently active and reference nodes in the
    94    *  file system that we are trying to unmount
    95    */
    96 
    97   if ( rtems_libio_is_open_files_in_fs( fs_root_loc.mt_entry ) == 1 ) {
    98     rtems_filesystem_freenode( &fs_root_loc );
    99     set_errno_and_return_minus_one( EBUSY );
    100   }
    101  
    102   /*
    103    * Allow the file system being unmounted on to do its cleanup.
    104    */
    105 
    106   if ((temp_mt_entry.mt_point_node.ops->unmount_h )( fs_root_loc.mt_entry ) != 0 ) {
    107     rtems_filesystem_freenode( &fs_root_loc );
    108     return -1;
    109   }
    110 
    111   /*
    112    * Run the unmount function for the subordinate file system.
    113    */
    114 
    115   if ((temp_mt_entry.mt_fs_root.ops->fsunmount_me_h )( fs_root_loc.mt_entry ) != 0){
    116     rtems_filesystem_freenode( &fs_root_loc );
    117     return -1;
    118   }
    119 
    120   /*
    121    *  Extract the mount table entry from the chain
    122    */
    123 
    124   Chain_Extract( ( Chain_Node * ) fs_root_loc.mt_entry );
    125 
    126   /*
    127    *  Free the memory associated with the extracted mount table entry.
    128    */
    129 
    130   rtems_filesystem_freenode( &fs_root_loc.mt_entry->mt_point_node );
    131   free( fs_root_loc.mt_entry );
    132   rtems_filesystem_freenode( &fs_root_loc );
    133 
    134   return 0;
     45rtems_boolean rtems_filesystem_nodes_equal(
     46  const rtems_filesystem_location_info_t   *loc1,
     47  const rtems_filesystem_location_info_t   *loc2
     48){
     49  return ( loc1->node_access == loc2->node_access );
    13550}
    13651
     
    14863 */
    14964
    150 int file_systems_below_this_mountpoint(
     65rtems_boolean file_systems_below_this_mountpoint(
    15166  const char                            *path,
    15267  rtems_filesystem_location_info_t      *fs_root_loc,
     
    15873
    15974  /*
    160    *  Is the path even a valid node name in the existing tree?
    161    */
    162 
    163   if ( rtems_filesystem_evaluate_path( path, 0x0, fs_root_loc, TRUE ) )
    164     return -1;
    165  
    166   /*
    167    * Verify this is the root node for the file system to be unmounted.
    168    */
    169 
    170   *fs_to_unmount = *fs_root_loc->mt_entry;
    171   if ( fs_to_unmount->mt_fs_root.node_access != fs_root_loc->node_access ){
    172     rtems_filesystem_freenode(fs_root_loc);
    173     set_errno_and_return_minus_one( EACCES );
    174   }
    175 
    176   /*
    17775   * Search the mount table for any mount entries referencing this
    17876   * mount entry.
     
    18482     the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
    18583     if (the_mount_entry->mt_point_node.mt_entry  == fs_root_loc->mt_entry ) {
    186         rtems_filesystem_freenode(fs_root_loc); 
    187         set_errno_and_return_minus_one( EBUSY );
     84        return TRUE;
    18885     }
    18986  }
    19087
     88  return FALSE;
     89}
     90
     91/*
     92 *  unmount
     93 *
     94 *  This routine will attempt to unmount the file system that has been
     95 *  is mounted a path.  If the operation is successful, 0 will
     96 *  be returned to the calling routine.  Otherwise, 1 will be returned.
     97 */
     98
     99int unmount(
     100  const char *path
     101)
     102{
     103  rtems_filesystem_location_info_t      loc;
     104  rtems_filesystem_location_info_t     *fs_root_loc;
     105  rtems_filesystem_location_info_t     *fs_mount_loc;
     106  rtems_filesystem_mount_table_entry_t *mt_entry;
     107
     108  /*
     109   *  Get
     110   *    The root node of the mounted filesytem.
     111   *    The node for the directory that the fileystem is mounted on.
     112   *    The mount entry that is being refered to.
     113   */
     114
     115  if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, TRUE ) )
     116    return -1;
     117
     118  mt_entry     = loc.mt_entry;
     119  fs_mount_loc = &mt_entry->mt_point_node;
     120  fs_root_loc  = &mt_entry->mt_fs_root;
     121       
     122  /*
     123   * Verify this is the root node for the file system to be unmounted.
     124   */
     125
     126  if ( !rtems_filesystem_nodes_equal( fs_root_loc, &loc) ){
     127    rtems_filesystem_freenode( &loc );
     128    set_errno_and_return_minus_one( EACCES );
     129  }
     130
     131  /*
     132   * Free the loc node and just use the nodes from the mt_entry .
     133   */
     134
     135  rtems_filesystem_freenode( &loc );
     136
     137  /*
     138   * Verify Unmount is supported by both filesystems.
     139   */
     140
     141  if ( !fs_mount_loc->ops->unmount_h )
     142    set_errno_and_return_minus_one( ENOTSUP );
     143
     144  if ( !fs_root_loc->ops->fsunmount_me_h )
     145    set_errno_and_return_minus_one( ENOTSUP );
     146
     147
     148  /*
     149   *  Verify the current node is not in this filesystem.
     150   *  XXX - Joel I have a question here wasn't code added
     151   *        that made the current node thread based instead
     152   *        of system based?  I thought it was but it doesn't
     153   *        look like it in this version.
     154   */
     155
     156  if ( rtems_filesystem_current.mt_entry == mt_entry )
     157    set_errno_and_return_minus_one( EBUSY );
     158
     159  /*
     160   *  Verify there are no file systems below the path specified
     161   */
     162
     163  if ( file_systems_below_this_mountpoint( path, fs_root_loc, mt_entry ) != 0 )
     164    set_errno_and_return_minus_one( EBUSY );
     165
     166  /*
     167   *  Run the file descriptor table to determine if there are any file
     168   *  descriptors that are currently active and reference nodes in the
     169   *  file system that we are trying to unmount
     170   */
     171
     172  if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
     173    set_errno_and_return_minus_one( EBUSY );
     174 
     175  /*
     176   * Allow the file system being unmounted on to do its cleanup.
     177   * If it fails it will set the errno to the approprate value
     178   * and the fileystem will not be modified.
     179   */
     180
     181  if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
     182    return -1;
     183
     184  /*
     185   *  Allow the mounted filesystem to unmark the use of the root node.
     186   *
     187   *  Run the unmount function for the subordinate file system.
     188   *
     189   *  If we fail to unmount the filesystem remount it on the base filesystems
     190   *  directory node.
     191   *
     192   *  NOTE:  Fatal error is called in a case which should never happen
     193   *         This was response was questionable but the best we could
     194   *         come up with.
     195   */
     196
     197  if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){
     198    if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
     199      rtems_fatal_error_occurred( 0 );
     200    return -1;
     201  }
     202
     203  /*
     204   *  Extract the mount table entry from the chain
     205   */
     206
     207  Chain_Extract( ( Chain_Node * ) mt_entry );
     208
     209  /*
     210   *  Free the memory node that was allocated in mount
     211   *  Free the memory associated with the extracted mount table entry.
     212   */
     213
     214  rtems_filesystem_freenode( fs_mount_loc );
     215  free( mt_entry );
     216
    191217  return 0;
    192218}
     219
     220
Note: See TracChangeset for help on using the changeset viewer.