Changeset 1bdff036 in rtems


Ignore:
Timestamp:
Feb 23, 2012, 4:57:27 PM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
6661435f
Parents:
2e0ce55
git-author:
Sebastian Huber <sebastian.huber@…> (02/23/12 16:57:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/13/12 11:24:15)
Message:

IMFS: Reference counting for nodes

The introduction of reference counting of nodes avoids the removal of
open nodes and potential usage of freed memory.

Location:
cpukit/libfs/src/imfs
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libfs/src/imfs/deviceio.c

    r2e0ce55 r1bdff036  
    8080    (void *) &args
    8181  );
    82 
    83   IMFS_check_node_remove( the_jnode );
    8482
    8583  return rtems_deviceio_errno( status );
  • cpukit/libfs/src/imfs/fifoimfs_init.c

    r2e0ce55 r1bdff036  
    3737  .fchmod_h = IMFS_fchmod,
    3838  .chown_h = IMFS_chown,
    39   .clonenod_h = rtems_filesystem_default_clonenode,
    40   .freenod_h = rtems_filesystem_default_freenode,
     39  .clonenod_h = IMFS_node_clone,
     40  .freenod_h = IMFS_node_free,
    4141  .mount_h = IMFS_mount,
    4242  .fsmount_me_h = fifoIMFS_initialize,
  • cpukit/libfs/src/imfs/imfs.h

    r2e0ce55 r1bdff036  
    167167  char                name[IMFS_NAME_MAX+1]; /* "basename" */
    168168  mode_t              st_mode;               /* File mode */
     169  unsigned short      reference_count;
    169170  nlink_t             st_nlink;              /* Link count */
    170171  ino_t               st_ino;                /* inode */
     
    275276extern int IMFS_memfile_maximum_size( void );
    276277
     278extern void IMFS_node_destroy( IMFS_jnode_t *node );
     279
     280extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
     281
     282extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
    277283
    278284extern rtems_filesystem_node_types_t IMFS_node_type(
     
    354360);
    355361
    356 extern int imfs_dir_close(
    357   rtems_libio_t *iop             /* IN  */
    358 );
    359 
    360362extern ssize_t imfs_dir_read(
    361363  rtems_libio_t *iop,              /* IN  */
     
    375377  int            oflag,           /* IN  */
    376378  mode_t         mode             /* IN  */
    377 );
    378 
    379 extern int memfile_close(
    380   rtems_libio_t *iop             /* IN  */
    381379);
    382380
     
    477475);
    478476
    479 extern void IMFS_create_orphan(
    480   IMFS_jnode_t *jnode
    481 );
    482 
    483 extern void IMFS_check_node_remove(
    484   IMFS_jnode_t *jnode
    485 );
    486 
    487477extern int IMFS_rmnod(
    488478  const rtems_filesystem_location_info_t *parentloc,
    489479  const rtems_filesystem_location_info_t *loc
    490480);
     481
     482/*
     483 *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
     484 */
     485#ifdef RTEMS_DEBUG
     486  #include <assert.h>
     487
     488  #define IMFS_assert(_x) assert(_x)
     489#else
     490  #define IMFS_assert(_x)
     491#endif
    491492
    492493static inline void IMFS_add_to_directory(
     
    501502static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
    502503{
     504  IMFS_assert( node->Parent != NULL );
    503505  node->Parent = NULL;
    504506  rtems_chain_extract_unprotected( &node->Node );
    505507}
    506508
    507 /*
    508  *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
    509  */
    510 #ifdef RTEMS_DEBUG
    511   #include <assert.h>
    512 
    513   #define IMFS_assert(_x) assert(_x)
    514 #else
    515   #define IMFS_assert(_x)
    516 #endif
    517 
    518509#ifdef __cplusplus
    519510}
  • cpukit/libfs/src/imfs/imfs_creat.c

    r2e0ce55 r1bdff036  
    124124   *  Fill in the basic information
    125125   */
     126  node->reference_count = 1;
    126127  node->st_nlink = 1;
    127128  node->type     = type;
  • cpukit/libfs/src/imfs/imfs_directory.c

    r2e0ce55 r1bdff036  
    128128}
    129129
    130 
    131 
    132 /*
    133  *  imfs_dir_close
    134  *
    135  *  This routine will be called by the generic close routine to cleanup any
    136  *  resources that have been allocated for the management of the file
    137  */
    138 
    139 int imfs_dir_close(
    140   rtems_libio_t  *iop
    141 )
    142 {
    143   /*
    144    *  The generic close routine handles the deallocation of the file control
    145    *  and associated memory. At present the imfs_dir_close simply
    146    *  returns a successful completion status.
    147    */
    148 
    149   return 0;
    150 }
    151 
    152 
    153 
    154130/*
    155131 *  imfs_dir_lseek
  • cpukit/libfs/src/imfs/imfs_eval.c

    r2e0ce55 r1bdff036  
    155155
    156156        if ( fs_root_ptr == NULL ) {
     157          --dir->reference_count;
     158          ++entry->reference_count;
    157159          currentloc->node_access = entry;
    158160          IMFS_Set_handlers( currentloc );
  • cpukit/libfs/src/imfs/imfs_fifo.c

    r2e0ce55 r1bdff036  
    5050
    5151  pipe_release(&JNODE2PIPE(jnode), iop);
    52 
    53   iop->flags &= ~LIBIO_FLAGS_OPEN;
    54   IMFS_check_node_remove(jnode);
    5552
    5653  IMFS_FIFO_RETURN(err);
  • cpukit/libfs/src/imfs/imfs_fsunmount.c

    r2e0ce55 r1bdff036  
    6464     if ( jnode->type != IMFS_DIRECTORY || jnode_has_no_children( jnode ) ) {
    6565        result = IMFS_rmnod( NULL, &loc );
    66         if (result != 0)
    67           rtems_fatal_error_occurred(0xdeadbeef);
     66        if ( result != 0 )
     67          rtems_fatal_error_occurred( 0xdeadbeef );
     68        IMFS_node_destroy( jnode );
    6869        jnode = next;
    6970     }
  • cpukit/libfs/src/imfs/imfs_handlers_directory.c

    r2e0ce55 r1bdff036  
    2424const rtems_filesystem_file_handlers_r IMFS_directory_handlers = {
    2525  imfs_dir_open,
    26   imfs_dir_close,
     26  rtems_filesystem_default_close,
    2727  imfs_dir_read,
    2828  rtems_filesystem_default_write,
  • cpukit/libfs/src/imfs/imfs_handlers_memfile.c

    r2e0ce55 r1bdff036  
    2424const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
    2525  memfile_open,
    26   memfile_close,
     26  rtems_filesystem_default_close,
    2727  memfile_read,
    2828  memfile_write,
  • cpukit/libfs/src/imfs/imfs_init.c

    r2e0ce55 r1bdff036  
    3535  .fchmod_h = IMFS_fchmod,
    3636  .chown_h = IMFS_chown,
    37   .clonenod_h = rtems_filesystem_default_clonenode,
    38   .freenod_h = rtems_filesystem_default_freenode,
     37  .clonenod_h = IMFS_node_clone,
     38  .freenod_h = IMFS_node_free,
    3939  .mount_h = IMFS_mount,
    4040  .fsmount_me_h = IMFS_initialize,
  • cpukit/libfs/src/imfs/imfs_initsupp.c

    r2e0ce55 r1bdff036  
    107107  return 0;
    108108}
     109
     110int IMFS_node_clone( rtems_filesystem_location_info_t *loc )
     111{
     112  IMFS_jnode_t *node = loc->node_access;
     113
     114  ++node->reference_count;
     115
     116  return 0;
     117}
     118
     119void IMFS_node_destroy( IMFS_jnode_t *node )
     120{
     121  IMFS_assert( node->reference_count == 0 );
     122
     123  switch ( node->type ) {
     124    case IMFS_MEMORY_FILE:
     125      IMFS_memfile_remove( node );
     126      break;
     127    case IMFS_SYM_LINK:
     128      free( node->info.sym_link.name );
     129      break;
     130    default:
     131      break;
     132  }
     133
     134  free( node );
     135}
     136
     137void IMFS_node_free( const rtems_filesystem_location_info_t *loc )
     138{
     139  IMFS_jnode_t *node = loc->node_access;
     140
     141  if ( node->reference_count == 1 ) {
     142    IMFS_node_destroy( node );
     143  } else {
     144    --node->reference_count;
     145  }
     146}
  • cpukit/libfs/src/imfs/imfs_link.c

    r2e0ce55 r1bdff036  
    3131  IMFS_types_union   info;
    3232  IMFS_jnode_t      *new_node;
     33  IMFS_jnode_t      *target;
     34
     35  target = targetloc->node_access;
     36  info.hard_link.link_node = target;
    3337
    3438  /*
    3539   *  Verify this node can be linked to.
    3640   */
    37   info.hard_link.link_node = targetloc->node_access;
    38   if ( info.hard_link.link_node->st_nlink >= LINK_MAX )
     41  if ( target->st_nlink >= LINK_MAX )
    3942    rtems_set_errno_and_return_minus_one( EMLINK );
    4043
     
    5760   * Increment the link count of the node being pointed to.
    5861   */
    59   info.hard_link.link_node->st_nlink++;
    60   IMFS_update_ctime( info.hard_link.link_node );
     62  target->reference_count++;
     63  target->st_nlink++;
     64  IMFS_update_ctime( target );
    6165
    6266  return 0;
  • cpukit/libfs/src/imfs/imfs_rmnod.c

    r2e0ce55 r1bdff036  
    2424#include "imfs.h"
    2525
    26 #include <stdlib.h>
    27 
    28 void IMFS_create_orphan( IMFS_jnode_t *jnode )
    29 {
    30   if ( jnode->Parent != NULL ) {
    31     IMFS_remove_from_directory( jnode );
    32   }
    33 
    34   --jnode->st_nlink;
    35 
    36   IMFS_update_ctime( jnode );
    37 }
    38 
    39 void IMFS_check_node_remove( IMFS_jnode_t *jnode )
    40 {
    41   if ( jnode->st_nlink < 1 ) {
    42     switch ( jnode->type ) {
    43       case IMFS_MEMORY_FILE:
    44         IMFS_memfile_remove( jnode );
    45         break;
    46       case IMFS_SYM_LINK:
    47         free( jnode->info.sym_link.name );
    48         break;
    49       default:
    50         break;
    51     }
    52 
    53     free( jnode );
    54   }
    55 }
    56 
    5726static int IMFS_rmnod_directory(
    5827  const rtems_filesystem_location_info_t *parentloc,
     
    6029)
    6130{
     31  int rv = 0;
    6232  IMFS_jnode_t *node = loc->node_access;
    63   int rv = 0;
    6433
    6534  if ( !rtems_chain_is_empty( &node->info.directory.Entries ) ) {
     
    12190
    12291  if ( rv == 0 ) {
    123     IMFS_create_orphan( node );
    124     IMFS_check_node_remove( node );
     92    --node->reference_count;
     93    --node->st_nlink;
     94    if ( node->Parent != NULL ) {
     95      IMFS_remove_from_directory( node );
     96    }
    12597  }
    12698
  • cpukit/libfs/src/imfs/memfile.c

    r2e0ce55 r1bdff036  
    111111
    112112  iop->size = the_jnode->info.file.size;
    113   return 0;
    114 }
    115 
    116 /*
    117  *  memfile_close
    118  *
    119  *  This routine processes the close() system call.  Note that there is
    120  *  nothing to flush or memory to free at this point.
    121  */
    122 int memfile_close(
    123   rtems_libio_t *iop
    124 )
    125 {
    126   IMFS_jnode_t   *the_jnode;
    127 
    128   the_jnode = iop->pathinfo.node_access;
    129 
    130   if (iop->flags & LIBIO_FLAGS_APPEND)
    131     iop->offset = the_jnode->info.file.size;
    132 
    133   IMFS_check_node_remove( the_jnode );
    134 
    135113  return 0;
    136114}
  • cpukit/libfs/src/imfs/miniimfs_init.c

    r2e0ce55 r1bdff036  
    3535  .fchmod_h = rtems_filesystem_default_fchmod,
    3636  .chown_h = rtems_filesystem_default_chown,
    37   .clonenod_h = rtems_filesystem_default_clonenode,
    38   .freenod_h = rtems_filesystem_default_freenode,
     37  .clonenod_h = IMFS_node_clone,
     38  .freenod_h = IMFS_node_free,
    3939  .mount_h = IMFS_mount,
    4040  .fsmount_me_h = miniIMFS_initialize,
Note: See TracChangeset for help on using the changeset viewer.