[rtems commit] IMFS: Lock the file system during directory reads

Joel Sherrill joel at rtems.org
Thu Mar 29 14:14:29 UTC 2012


Module:    rtems
Branch:    master
Commit:    62e9ff7623fbd9b61e56c0553dba32cb4d5aa46c
Changeset: http://git.rtems.org/rtems/commit/?id=62e9ff7623fbd9b61e56c0553dba32cb4d5aa46c

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Feb 21 17:21:05 2012 +0100

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.

---

 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 8ef05b4..fc687e4 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;
 }
 




More information about the vc mailing list