diff --git a/ChangeLog b/ChangeLog
index 485db96b22bf16003c340f163bef68e677e1d0fe..e40f8dc3d37042da1b1ac509c1de38d3f32c1c17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -181,5 +181,6 @@
 	* tools/Makefile.mkconfig: Under Cygwin, executable has a different name
 	* tools/mkdeps.sh & arch/arm/src/Makefile: Corrected a problem makeing dependencies
 	* tools/zipme.sh: Force directory name to be nuttx-xx.yy.zz
+	* fs/fs_opendir.c: Correct errors in semaphore usage that can cause deadlock.
 	* Started m68322
 
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 3d765a86794ed54764e05483e3ff483db130a892..9e4ca3b7d6da760dfe141aaac54648ee977a1e4f 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -616,6 +616,7 @@ Other memory:
 	* tools/Makefile.mkconfig: Under Cygwin, executable has a different name
 	* tools/mkdeps.sh & arch/arm/src/Makefile: Corrected a problem makeing dependencies
 	* tools/zipme.sh: Force directory name to be nuttx-xx.yy.zz
+	* fs/fs_opendir.c: Correct errors in semaphore usage that can cause deadlock.
 	* Started m68322
 </pre></ul>
 
diff --git a/fs/fs_opendir.c b/fs/fs_opendir.c
index 6890de1ea25f8a5c4a6b1a972fa7cbfc3a78afe8..3fa32fc1ed4a1a8873444f2e694a7e65b7e67433 100644
--- a/fs/fs_opendir.c
+++ b/fs/fs_opendir.c
@@ -94,9 +94,9 @@ FAR DIR *opendir(const char *path)
    * request for the root inode.
    */
 
+  inode_semtake();
   if (!path || *path == 0 || strcmp(path, "/") == 0)
     {
-       inode_semgive();
        inode = root_inode;
        isroot = TRUE;
     }
@@ -106,12 +106,12 @@ FAR DIR *opendir(const char *path)
 
        if (*path != '/')
         {
-          return NULL;
+          ret = -ENOTDIR;
+          goto errout_with_semaphore;
         }
 
       /* Find the node matching the path. */
 
-      inode_semtake();
       inode = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, &relpath);
     }
 
@@ -166,9 +166,11 @@ FAR DIR *opendir(const char *path)
            goto errout_with_direntry;
         }
 
-      /* Take reference to the mountpoint inode (fd_root) */
+      /* Take reference to the mountpoint inode (fd_root).  Note that we do
+      * not use inode_addref() because we already hold the tree semaphore.
+      */
 
-      inode_addref(inode);
+      inode->i_crefs++;
 
       /* Perform the opendir() operation */
 
@@ -199,10 +201,12 @@ FAR DIR *opendir(const char *path)
 
       /* It looks we have a valid psuedo-filesystem node.  Take two references
       * on the inode -- one for the parent (fd_root) and one for the child (fd_next).
+      * Note that we do not call inode_addref because we are holding
+      * the tree semaphore and that would result in deadlock.
       */
 
-      inode_addref(inode); 
-      inode_addref(inode); 
+      inode->i_crefs++;
+      inode->i_crefs++;
       dir->u.psuedo.fd_next = inode; /* This is the next node to use for readdir() */
 
       /* Flag the inode as belonging to the psuedo-filesystem */