Changeset baef823c in rtems


Ignore:
Timestamp:
Sep 13, 2017, 7:22:19 AM (22 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
ac74162
Parents:
98041b68
git-author:
Sebastian Huber <sebastian.huber@…> (09/13/17 07:22:19)
git-committer:
Sebastian Huber <sebastian.huber@…> (09/15/17 08:29:34)
Message:

libio: Add hold/drop iop reference

Check iop reference count in close() and return -1 with errno set to
EBUSY in case the file descriptor is still in use.

Update #3132.

Files:
8 added
23 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/include/rtems/libio.h

    r98041b68 rbaef823c  
    3838#include <rtems/fs.h>
    3939#include <rtems/chain.h>
     40#include <rtems/score/atomic.h>
    4041
    4142#ifdef __cplusplus
     
    13201321  rtems_driver_name_t                    *driver;
    13211322  off_t                                   offset;    /* current offset into file */
    1322   uint32_t                                flags;
     1323  Atomic_Uint                             flags;
    13231324  rtems_filesystem_location_info_t        pathinfo;
    13241325  uint32_t                                data0;     /* private to "driver" */
     
    13721373#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800U  /* close on process exec() */
    13731374#define LIBIO_FLAGS_READ_WRITE    (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
     1375#define LIBIO_FLAGS_REFERENCE_INC 0x1000U
    13741376
    13751377/** @} */
    13761378
    1377 static inline uint32_t rtems_libio_iop_flags( const rtems_libio_t *iop )
     1379static inline unsigned int rtems_libio_iop_flags( const rtems_libio_t *iop )
    13781380{
    1379   return iop->flags;
     1381  return _Atomic_Load_uint( &iop->flags, ATOMIC_ORDER_RELAXED );
    13801382}
    13811383
  • cpukit/libcsupport/include/rtems/libio_.h

    r98041b68 rbaef823c  
    105105)
    106106{
    107   iop->flags = LIBIO_FLAGS_OPEN | flags;
     107  _Atomic_Store_uint(
     108    &iop->flags,
     109    LIBIO_FLAGS_OPEN | flags,
     110    ATOMIC_ORDER_RELEASE
     111  );
    108112}
    109113
     
    116120 * @return The previous flags.
    117121 */
    118 static inline uint32_t rtems_libio_iop_flags_set(
     122static inline unsigned int rtems_libio_iop_flags_set(
    119123  rtems_libio_t *iop,
    120   uint32_t       set
    121 )
    122 {
    123   uint32_t flags;
    124 
    125   flags = iop->flags;
    126   iop->flags = flags | set;
    127   return flags;
     124  unsigned int   set
     125)
     126{
     127  return _Atomic_Fetch_or_uint( &iop->flags, set, ATOMIC_ORDER_RELAXED );
    128128}
    129129
     
    136136 * @return The previous flags.
    137137 */
    138 static inline uint32_t rtems_libio_iop_flags_clear(
     138static inline unsigned int rtems_libio_iop_flags_clear(
    139139  rtems_libio_t *iop,
    140   uint32_t       clear
    141 )
    142 {
    143   uint32_t flags;
    144 
    145   flags = iop->flags;
    146   iop->flags = flags & ~clear;
    147   return flags;
     140  unsigned int   clear
     141)
     142{
     143  return _Atomic_Fetch_and_uint( &iop->flags, ~clear, ATOMIC_ORDER_RELAXED );
    148144}
    149145
     
    160156{
    161157  return &rtems_libio_iops[ fd ];
     158}
     159
     160/**
     161 * @brief Holds a refernece to the iop.
     162 *
     163 * @param[in] iop The iop.
     164 *
     165 * @return The flags corresponding to the specified iop.
     166 */
     167static inline unsigned int rtems_libio_iop_hold( rtems_libio_t *iop )
     168{
     169  return _Atomic_Fetch_add_uint(
     170    &iop->flags,
     171    LIBIO_FLAGS_REFERENCE_INC,
     172    ATOMIC_ORDER_ACQUIRE
     173  );
     174}
     175
     176/**
     177 * @brief Drops a refernece to the iop.
     178 *
     179 * @param[in] iop The iop.
     180 */
     181static inline void rtems_libio_iop_drop( rtems_libio_t *iop )
     182{
     183  _Atomic_Fetch_sub_uint(
     184    &iop->flags,
     185    LIBIO_FLAGS_REFERENCE_INC,
     186    ATOMIC_ORDER_RELEASE
     187  );
    162188}
    163189
     
    193219#define LIBIO_GET_IOP( _fd, _iop ) \
    194220  do { \
    195     uint32_t _flags; \
     221    unsigned int _flags; \
    196222    if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
    197223      rtems_set_errno_and_return_minus_one( EBADF ); \
    198224    } \
    199225    _iop = rtems_libio_iop( _fd ); \
    200     _flags = _iop->flags; \
     226    _flags = rtems_libio_iop_hold( _iop ); \
    201227    if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
     228      rtems_libio_iop_drop( _iop ); \
    202229      rtems_set_errno_and_return_minus_one( EBADF ); \
    203230    } \
     
    212239#define LIBIO_GET_IOP_WITH_ACCESS( _fd, _iop, _access_flags, _access_error ) \
    213240  do { \
    214     uint32_t _flags; \
    215     uint32_t _mandatory; \
     241    unsigned int _flags; \
     242    unsigned int _mandatory; \
    216243    if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
    217244      rtems_set_errno_and_return_minus_one( EBADF ); \
    218245    } \
    219246    _iop = rtems_libio_iop( _fd ); \
    220     _flags = _iop->flags; \
     247    _flags = rtems_libio_iop_hold( _iop ); \
    221248    _mandatory = LIBIO_FLAGS_OPEN | ( _access_flags ); \
    222249    if ( ( _flags & _mandatory ) != _mandatory ) { \
    223250      int _error; \
     251      rtems_libio_iop_drop( _iop ); \
    224252      if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
    225253        _error = EBADF; \
     
    358386 * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
    359387 */
    360 uint32_t rtems_libio_fcntl_flags( int fcntl_flags );
     388unsigned int rtems_libio_fcntl_flags( int fcntl_flags );
    361389
    362390/**
    363391 * Convert RTEMS internal flags to UNIX fnctl(2) flags
    364392 */
    365 int rtems_libio_to_fcntl_flags( uint32_t flags );
     393int rtems_libio_to_fcntl_flags( unsigned int flags );
    366394
    367395/**
     
    933961  const struct iovec        *iov,
    934962  int                        iovcnt,
    935   uint32_t                   flags,
     963  unsigned int               flags,
    936964  rtems_libio_iovec_adapter  adapter
    937965)
     
    9791007  }
    9801008
     1009  rtems_libio_iop_drop( iop );
    9811010  return total;
    9821011}
  • cpukit/libcsupport/src/close.c

    r98041b68 rbaef823c  
    2525)
    2626{
    27   rtems_libio_t      *iop;
    28   int                 rc;
     27  rtems_libio_t *iop;
     28  unsigned int   flags;
     29  int            rc;
    2930
    30   LIBIO_GET_IOP( fd, iop );
     31  if ( (uint32_t) fd >= rtems_libio_number_iops ) {
     32    rtems_set_errno_and_return_minus_one( EBADF );
     33  }
    3134
    32   rtems_libio_iop_flags_clear( iop, LIBIO_FLAGS_OPEN );
     35  iop = rtems_libio_iop( fd );
     36  flags = rtems_libio_iop_flags( iop );
     37
     38  while ( true ) {
     39    unsigned int desired;
     40    bool         success;
     41
     42    if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) {
     43      rtems_set_errno_and_return_minus_one( EBADF );
     44    }
     45
     46    /* The expected flags */
     47    flags &= LIBIO_FLAGS_REFERENCE_INC - 1U;
     48
     49    desired = flags & ~LIBIO_FLAGS_OPEN;
     50    success = _Atomic_Compare_exchange_uint(
     51      &iop->flags,
     52      &flags,
     53      desired,
     54      ATOMIC_ORDER_ACQ_REL,
     55      ATOMIC_ORDER_RELAXED
     56    );
     57
     58    if ( success ) {
     59      break;
     60    }
     61
     62    if ( ( flags & ~( LIBIO_FLAGS_REFERENCE_INC - 1U ) ) != 0 ) {
     63      rtems_set_errno_and_return_minus_one( EBUSY );
     64    }
     65  }
    3366
    3467  rc = (*iop->pathinfo.handlers->close_h)( iop );
  • cpukit/libcsupport/src/fchdir.c

    r98041b68 rbaef823c  
    6060  }
    6161  rtems_filesystem_instance_unlock( &iop->pathinfo );
     62  rtems_libio_iop_drop( iop );
    6263
    6364  if ( rv == 0 ) {
  • cpukit/libcsupport/src/fchmod.c

    r98041b68 rbaef823c  
    7676  rtems_filesystem_instance_unlock( &iop->pathinfo );
    7777
     78  rtems_libio_iop_drop( iop );
     79
    7880  return rv;
    7981}
  • cpukit/libcsupport/src/fchown.c

    r98041b68 rbaef823c  
    7373  rtems_filesystem_instance_unlock( &iop->pathinfo );
    7474
     75  rtems_libio_iop_drop( iop );
     76
    7577  return rv;
    7678}
  • cpukit/libcsupport/src/fcntl.c

    r98041b68 rbaef823c  
    214214    }
    215215  }
     216
     217  rtems_libio_iop_drop( iop );
    216218  return ret;
    217219}
  • cpukit/libcsupport/src/fdatasync.c

    r98041b68 rbaef823c  
    2929{
    3030  rtems_libio_t *iop;
     31  int            rv;
    3132
    3233  LIBIO_GET_IOP_WITH_ACCESS( fd, iop, LIBIO_FLAGS_WRITE, EBADF );
     
    3637   */
    3738
    38   return (*iop->pathinfo.handlers->fdatasync_h)( iop );
     39  rv = (*iop->pathinfo.handlers->fdatasync_h)( iop );
     40  rtems_libio_iop_drop( iop );
     41  return rv;
    3942}
  • cpukit/libcsupport/src/fpathconf.c

    r98041b68 rbaef823c  
    8383      break;
    8484    default:
    85       rtems_set_errno_and_return_minus_one( EINVAL );
     85      errno = EINVAL;
     86      return_value = -1;
    8687      break;
    8788  }
    8889
     90  rtems_libio_iop_drop( iop );
    8991  return return_value;
    9092}
  • cpukit/libcsupport/src/fstat.c

    r98041b68 rbaef823c  
    2727{
    2828  rtems_libio_t *iop;
     29  int            rv;
    2930
    3031  /*
     
    4546  memset( sbuf, 0, sizeof(struct stat) );
    4647
    47   return (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, sbuf );
     48  rv = (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, sbuf );
     49  rtems_libio_iop_drop( iop );
     50  return rv;
    4851}
    4952
  • cpukit/libcsupport/src/fsync.c

    r98041b68 rbaef823c  
    3232{
    3333  rtems_libio_t *iop;
     34  int            rv;
    3435
    3536  LIBIO_GET_IOP( fd, iop );
     
    3940   */
    4041
    41   return (*iop->pathinfo.handlers->fsync_h)( iop );
     42  rv = (*iop->pathinfo.handlers->fsync_h)( iop );
     43  rtems_libio_iop_drop( iop );
     44  return rv;
    4245}
  • cpukit/libcsupport/src/ftruncate.c

    r98041b68 rbaef823c  
    3333
    3434    rv = (*iop->pathinfo.handlers->ftruncate_h)( iop, length );
     35    rtems_libio_iop_drop( iop );
    3536  } else {
    3637    errno = EINVAL;
  • cpukit/libcsupport/src/ioctl.c

    r98041b68 rbaef823c  
    5252
    5353  va_end( ap );
     54  rtems_libio_iop_drop( iop );
    5455  return rc;
    5556}
  • cpukit/libcsupport/src/libio.c

    r98041b68 rbaef823c  
    5959};
    6060
    61 uint32_t rtems_libio_fcntl_flags( int fcntl_flags )
     61unsigned int rtems_libio_fcntl_flags( int fcntl_flags )
    6262{
    63   uint32_t   flags = 0;
     63  unsigned int   flags = 0;
    6464  uint32_t   access_modes;
    6565
     
    6868   */
    6969
    70   access_modes = (uint32_t) (fcntl_flags & O_ACCMODE);
     70  access_modes = (unsigned int) (fcntl_flags & O_ACCMODE);
    7171  fcntl_flags &= ~O_ACCMODE;
    7272  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
     
    7676   */
    7777
    78   flags |= rtems_assoc_local_by_remote_bitfield(
     78  flags |= (unsigned int ) rtems_assoc_local_by_remote_bitfield(
    7979    status_flags_assoc,
    8080    (uint32_t) fcntl_flags
     
    8484}
    8585
    86 int rtems_libio_to_fcntl_flags( uint32_t flags )
     86int rtems_libio_to_fcntl_flags( unsigned int flags )
    8787{
    8888  int fcntl_flags = 0;
  • cpukit/libcsupport/src/lseek.c

    r98041b68 rbaef823c  
    2121{
    2222  rtems_libio_t *iop;
     23  off_t          rv;
    2324
    2425  LIBIO_GET_IOP( fd, iop );
    2526
    26   return (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence );
     27  rv = (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence );
     28  rtems_libio_iop_drop( iop );
     29  return rv;
    2730}
    2831
  • cpukit/libcsupport/src/open.c

    r98041b68 rbaef823c  
    100100  rtems_filesystem_eval_path_cleanup( &ctx );
    101101
    102   iop->flags = rtems_libio_fcntl_flags( oflag );
     102  _Atomic_Store_uint(
     103    &iop->flags,
     104    rtems_libio_fcntl_flags( oflag ),
     105    ATOMIC_ORDER_RELAXED
     106  );
    103107
    104108  rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode );
  • cpukit/libcsupport/src/read.c

    r98041b68 rbaef823c  
    3232{
    3333  rtems_libio_t *iop;
     34  ssize_t        n;
    3435
    3536  rtems_libio_check_buffer( buffer );
     
    4142   *  Now process the read().
    4243   */
    43   return (*iop->pathinfo.handlers->read_h)( iop, buffer, count );
     44  n = (*iop->pathinfo.handlers->read_h)( iop, buffer, count );
     45  rtems_libio_iop_drop( iop );
     46  return n;
    4447}
    4548
  • cpukit/libcsupport/src/write.c

    r98041b68 rbaef823c  
    3535{
    3636  rtems_libio_t *iop;
     37  ssize_t        n;
    3738
    3839  rtems_libio_check_buffer( buffer );
     
    4445   *  Now process the write() request.
    4546   */
    46   return (*iop->pathinfo.handlers->write_h)( iop, buffer, count );
     47  n = (*iop->pathinfo.handlers->write_h)( iop, buffer, count );
     48  rtems_libio_iop_drop( iop );
     49  return n;
    4750}
  • cpukit/posix/src/shmopen.c

    r98041b68 rbaef823c  
    226226  size_t len;
    227227  Objects_Get_by_name_error obj_err;
    228   uint32_t flags;
     228  unsigned int flags;
    229229
    230230  if ( shm_check_oflag( oflag ) != 0 ) {
  • testsuites/fstests/Makefile.am

    r98041b68 rbaef823c  
    33_SUBDIRS  =
    44_SUBDIRS += fsbdpart01
     5_SUBDIRS += fsclose01
    56_SUBDIRS += fsdosfsformat01
    67_SUBDIRS += fsdosfsname01
  • testsuites/fstests/configure.ac

    r98041b68 rbaef823c  
    7979AC_CONFIG_FILES([Makefile
    8080fsbdpart01/Makefile
     81fsclose01/Makefile
    8182fsdosfsformat01/Makefile
    8283fsdosfsname01/Makefile
  • testsuites/sptests/Makefile.am

    r98041b68 rbaef823c  
    3434    spsem_err02 sptask_err01 spevent_err03 sptask_err03 sptask_err02 \
    3535    sptask_err04 spclock_err01
     36_SUBDIRS += spintrcritical24
    3637_SUBDIRS += spfatal29
    3738_SUBDIRS += spfatal30
  • testsuites/sptests/configure.ac

    r98041b68 rbaef823c  
    3737# Explicitly list all Makefiles here
    3838AC_CONFIG_FILES([Makefile
     39spintrcritical24/Makefile
    3940spfatal31/Makefile
    4041spfatal30/Makefile
Note: See TracChangeset for help on using the changeset viewer.