diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-02-21 17:21:05 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-03-13 12:24:15 +0100 |
commit | 316507ab91ecabe73db1af03d74be398e24837b8 (patch) | |
tree | 590dfc503c2755ee657b6361fe8ddf584896a4f8 | |
parent | IMFS: Do not check for unsupported types (diff) | |
download | rtems-316507ab91ecabe73db1af03d74be398e24837b8.tar.bz2 |
IMFS: Lock the file system during directory reads
Other threads may add or remove directory entries during a read of the
directory. Use the file system instance lock for protection.
-rw-r--r-- | cpukit/libfs/src/imfs/imfs_directory.c | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/cpukit/libfs/src/imfs/imfs_directory.c b/cpukit/libfs/src/imfs/imfs_directory.c index 8ef05b4d1d..fc687e4331 100644 --- a/cpukit/libfs/src/imfs/imfs_directory.c +++ b/cpukit/libfs/src/imfs/imfs_directory.c @@ -81,34 +81,29 @@ ssize_t imfs_dir_read( int last_entry; struct dirent tmp_dirent; + rtems_filesystem_instance_lock( &iop->pathinfo ); + the_jnode = (IMFS_jnode_t *)iop->pathinfo.node_access; the_chain = &the_jnode->info.directory.Entries; - if ( rtems_chain_is_empty( the_chain ) ) - return 0; - /* Move to the first of the desired directory entries */ - the_node = rtems_chain_first( the_chain ); bytes_transferred = 0; first_entry = iop->offset; /* protect against using sizes that are not exact multiples of the */ /* -dirent- size. These could result in unexpected results */ - last_entry = first_entry + (count/sizeof(struct dirent)) * sizeof(struct dirent); + last_entry = first_entry + + (count / sizeof( struct dirent )) * sizeof( struct dirent ); /* The directory was not empty so try to move to the desired entry in chain*/ for ( - current_entry = 0; - current_entry < last_entry; - current_entry = current_entry + sizeof(struct dirent) ){ - - if ( rtems_chain_is_tail( the_chain, the_node ) ){ - /* We hit the tail of the chain while trying to move to the first */ - /* entry in the read */ - return bytes_transferred; /* Indicate that there are no more */ - /* entries to return */ - } - + current_entry = 0, + the_node = rtems_chain_first( the_chain ); + current_entry < last_entry + && !rtems_chain_is_tail( the_chain, the_node ); + current_entry += sizeof( struct dirent ), + the_node = rtems_chain_next( the_node ) + ) { if( current_entry >= first_entry ) { /* Move the entry to the return buffer */ tmp_dirent.d_off = current_entry; @@ -122,14 +117,13 @@ ssize_t imfs_dir_read( (void *)&tmp_dirent, sizeof( struct dirent ) ); - iop->offset = iop->offset + sizeof(struct dirent); - bytes_transferred = bytes_transferred + sizeof( struct dirent ); + iop->offset += sizeof( struct dirent ); + bytes_transferred += sizeof( struct dirent ); } - - the_node = the_node->next; } - /* Success */ + rtems_filesystem_instance_unlock( &iop->pathinfo ); + return bytes_transferred; } |