diff --git a/ChangeLog b/ChangeLog
index c6d46b359ac82d8a3c3f09f571f7364951c66f96..060eb3f01181d4322a67b35513310d1846b5839b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -141,5 +141,7 @@
 0.2.6 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
 	* Added unlink(), mkdir(), rmdir(), and rename()
+	* Fixed several serious FAT errors with oflags handling (&& instead of &)
+	* Added FAT support for unlink() and rmdir()
 	* Started m68322
 
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 726a5a5c5fd593c403eee0bb459f6c7cd731a223..49db96df206a7c4e7847aebe5f6a2c5bae07d8c8 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -186,6 +186,9 @@
    The 8th release of NuttX (nuttx-0.2.5) is available for download
    from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
    website.
+   The change log associated with the release is available <a href="#currentrelease">here</a>.
+   Unreleased changes after this release are avalable in CVS.
+   These unreleased changes are listed <a href="#pendingchanges">here</a>.
 </p>
 
 <table width ="100%">
@@ -376,6 +379,35 @@ Other memory:
   </tr>
 </table>
 
+<center><table width ="80%">
+<tr>
+  <td><img src="favicon.ico"></td>
+   <td>
+      <a href="#olderreleases">Change Logs for Older Releases</a><br>
+   </td>
+</tr>
+<tr>
+  <td><img src="favicon.ico"></td>
+   <td>
+      <a href="#currentrelease">ChangeLog for Current Release</a><br>
+   </td>
+</tr>
+<tr>
+  <td><img src="favicon.ico"></td>
+   <td>
+      <a href="#pendingchanges">Unreleased Changes</a>
+   </td>
+</tr>
+</table></center>
+
+<table width ="100%">
+  <tr bgcolor="#e4e4e4">
+  <td>
+    <a name="olderreleases>Change Logs for Older Releases</a>
+  </td>
+  </tr>
+</table>
+
 <ul><pre>
 0.1.0 2007-03-09  Gregory Nutt <spudmonkey@racsa.co.cr>
 
@@ -499,7 +531,17 @@ Other memory:
 	* Logic from arch/c5471 and arch/dm320 combined into arch/arm.
 	  arch/c5471 and arch/dm320 are deprecated and will be removed
 	  when the new c5471 and dm320 logic is verified.
+</pre></ul>
 
+<table width ="100%">
+  <tr bgcolor="#e4e4e4">
+  <td>
+    <a name="currentrelease">ChangeLog for Current Release</a>
+  </td>
+  </tr>
+</table>
+
+<pre><ul>
 0.2.5 2007-05-19 Gregory Nutt <spudmonkey@racsa.co.cr>
 
 	* Corrected some build/configuration issues introduced with the
@@ -516,10 +558,22 @@ Other memory:
 	* close() was not closing the underlying device.
 	* Added fsync()
 	* Added strspn() and strcspn()
+</pre></ul>
+
+<table width ="100%">
+  <tr bgcolor="#e4e4e4">
+  <td>
+    <a name="pendingchanges">Unreleased Changes</a>
+  </td>
+  </tr>
+</table>
 
+<pre><ul>
 0.2.6 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
 	* Added unlink(), mkdir(), rmdir(), and rename()
+	* Fixed several serious FAT errors with oflags handling (&& instead of &)
+	* Added FAT support for unlink() and rmdir()
 	* Started m68322
 </pre></ul>
 
diff --git a/arch/sim/src/up_deviceimage.c b/arch/sim/src/up_deviceimage.c
index 9a28f4edda9f5536667e30a6d18ec5e79dacd622..70dfc9cab1ba48aa750f621b10df981c07695828 100644
--- a/arch/sim/src/up_deviceimage.c
+++ b/arch/sim/src/up_deviceimage.c
@@ -82,7 +82,11 @@
  *   xxd -g 1 nuttx-test.vfat.gz >some-file
  *
  * Then manually massaged from the gzip xxd output to zlib format.  See
- * http://www.faqs.org/rfcs/rfc1952.html
+ * http://www.faqs.org/rfcs/rfc1952.html.  This amounts to:
+ *
+ *   Remove all of the leading bytes through the null terminator of the file name
+ *   Remove the last 8 bytes
+ *   Add 0x08, 0x1d to the beginning.
  */
 
 static const unsigned char g_vfatdata[] =
diff --git a/examples/mount/mount_main.c b/examples/mount/mount_main.c
index 09dc8e189624a192aaf1c39567b4bc0402106819..75cc3c2cef4b8b95751c9d1e678b742529cc0173 100644
--- a/examples/mount/mount_main.c
+++ b/examples/mount/mount_main.c
@@ -63,6 +63,7 @@ static const char g_source[]         = "/dev/blkdev";
 static const char g_target[]         = "/mnt/fs";
 static const char g_filesystemtype[] = "vfat";
 
+static const char g_testdir1[]       = "/mnt/fs/TestDir";
 static const char g_testfile1[]      = "/mnt/fs/TestDir/TestFile.txt";
 static const char g_testfile2[]      = "/mnt/fs/TestDir/WritTest.txt";
 static const char g_testmsg[]        = "This is a write test";
@@ -93,6 +94,8 @@ int user_start(int argc, char *argv[])
   int  nbytes;
   int  ret;
 
+  /* Mount the test file system (see arch/sim/src/up_deviceimage.c */
+
   printf("main: mounting %s filesystem at target=%s with source=%s\n",
          g_filesystemtype, g_target, g_source);
 
@@ -101,12 +104,15 @@ int user_start(int argc, char *argv[])
 
   if (ret == 0)
     {
+      /* Read a test file that is already on the test file system image */
+
       printf("main: opening %s for reading\n", g_testfile1);
 
       int fd = open(g_testfile1, O_RDONLY);
       if (fd < 0)
         {
-          printf("main: failed to open %s, errno=%d\n", g_testfile1, *get_errno_ptr());
+          printf("main: ERROR failed to open %s, errno=%d\n",
+                 g_testfile1, *get_errno_ptr());
         }
       else
         {
@@ -114,7 +120,8 @@ int user_start(int argc, char *argv[])
           nbytes = read(fd, buffer, 128);
           if (nbytes < 0)
             {
-              printf("main: failed to read from %s, errno=%d\n", g_testfile1, *get_errno_ptr());
+              printf("main: ERROR failed to read from %s, errno=%d\n",
+                     g_testfile1, *get_errno_ptr());
             }
           else
           {
@@ -124,19 +131,23 @@ int user_start(int argc, char *argv[])
           close(fd);
         }
 
+      /* Write a test file into a pre-existing file on the test file system */
+
       printf("main: opening %s for writing\n", g_testfile2);
 
       fd = open(g_testfile2, O_WRONLY|O_CREAT|O_TRUNC, 0644);
       if (fd < 0)
         {
-          printf("main: failed to open %s for writing, errno=%d\n", g_testfile2, *get_errno_ptr());
+          printf("main: ERROR failed to open %s for writing, errno=%d\n",
+                 g_testfile2, *get_errno_ptr());
         }
       else
         {
           int nbytes = write(fd, g_testmsg, strlen(g_testmsg));
           if (nbytes < 0)
             {
-              printf("main: failed to write to %s, errno=%d\n", g_testfile2, *get_errno_ptr());
+              printf("main: ERROR failed to write to %s, errno=%d\n",
+                     g_testfile2, *get_errno_ptr());
             }
           else
             {
@@ -145,12 +156,15 @@ int user_start(int argc, char *argv[])
           close(fd);
         }
 
+      /* Read the file that we just wrote */
+
       printf("main: opening %s for reading\n", g_testfile2);
 
       fd = open(g_testfile2, O_RDONLY);
       if (fd < 0)
         {
-          printf("main: failed to open %s for reading, errno=%d\n", g_testfile2, *get_errno_ptr());
+          printf("main: ERRORfailed to open %s for reading, errno=%d\n",
+                 g_testfile2, *get_errno_ptr());
         }
       else
         {
@@ -158,7 +172,8 @@ int user_start(int argc, char *argv[])
           nbytes = read(fd, buffer, 128);
           if (nbytes < 0)
             {
-              printf("main: failed to read from %s, errno=%d\n", g_testfile2, *get_errno_ptr());
+              printf("main: ERROR failed to read from %s, errno=%d\n",
+                     g_testfile2, *get_errno_ptr());
             }
           else
           {
@@ -168,8 +183,124 @@ int user_start(int argc, char *argv[])
           close(fd);
         }
 
+      /* Try rmdir() against a file on the directory.  It should fail with ENOTDIR */
+
+      printf("main: Try rmdir(%s)\n", g_testfile1);
+
+      ret = rmdir(g_testfile1);
+      if (ret == 0)
+        {
+          printf("main: ERROR rmdir(%s) succeeded\n", g_testfile1);
+        }
+      else if (*get_errno_ptr() != ENOTDIR)
+      {
+          printf("main: ERROR rmdir(%s) failed with errno=%d\n",
+                     g_testfile1, *get_errno_ptr());
+      }
+
+      /* Try rmdir() against the test directory.  It should fail with ENOTEMPTY */
+
+      printf("main: Try rmdir(%s)\n", g_testdir1);
+
+      ret = rmdir(g_testdir1);
+      if (ret == 0)
+        {
+          printf("main: ERROR rmdir(%s) succeeded\n", g_testdir1);
+        }
+      else if (*get_errno_ptr() != ENOTEMPTY)
+        {
+          printf("main: ERROR rmdir(%s) failed with errno=%d\n",
+                     g_testdir1, *get_errno_ptr());
+        }
+
+      /* Try unlink() against the test directory.  It should fail with EISDIR */
+
+      printf("main: Try unlink(%s)\n", g_testdir1);
+
+      ret = unlink(g_testdir1);
+      if (ret == 0)
+        {
+          printf("main: ERROR unlink(%s) succeeded\n", g_testdir1);
+        }
+      else if (*get_errno_ptr() != EISDIR)
+        {
+          printf("main: ERROR unlink(%s) failed with errno=%d\n",
+                     g_testdir1, *get_errno_ptr());
+        }
+
+      /* Try unlink() against the test file1.  It should succeed. */
+
+      printf("main: Try unlink(%s)\n", g_testfile1);
+
+      ret = unlink(g_testfile1);
+      if (ret != 0)
+        {
+          printf("main: ERROR unlink(%s) failed with errno=%d\n",
+                     g_testfile1, *get_errno_ptr());
+        }
+
+      /* Attempt to open testfile1 should fail with ENOENT */
+
+      printf("main: Try open(%s) for reading\n", g_testfile1);
+
+      fd = open(g_testfile1, O_RDONLY);
+      if (fd >= 0)
+        {
+          printf("main: ERROR open(%s) succeeded\n", g_testfile1);
+          close(fd);
+        }
+      else if (*get_errno_ptr() != ENOENT)
+        {
+          printf("main: ERROR open(%s) failed with errno=%d\n",
+                     g_testfile1, *get_errno_ptr());
+        }
+
+      /* Try rmdir() against the test directory.  It should still fail with ENOTEMPTY */
+
+      printf("main: Try rmdir(%s)\n", g_testdir1);
+
+      ret = rmdir(g_testdir1);
+      if (ret == 0)
+        {
+          printf("main: ERROR rmdir(%s) succeeded\n", g_testdir1);
+        }
+      else if (*get_errno_ptr() != ENOTEMPTY)
+        {
+          printf("main: ERROR rmdir(%s) failed with errno=%d\n",
+                     g_testdir1, *get_errno_ptr());
+        }
+
+      /* Try unlink() against the test file2.  It should succeed. */
+
+      printf("main: Try unlink(%s)\n", g_testfile2);
+
+      ret = unlink(g_testfile2);
+      if (ret != 0)
+        {
+          printf("main: ERROR unlink(%s) failed with errno=%d\n",
+                     g_testfile2, *get_errno_ptr());
+        }
+
+      /* Try rmdir() against the test directory.  It should now succeed. */
+
+      printf("main: Try rmdir(%s)\n", g_testdir1);
+
+      ret = rmdir(g_testdir1);
+      if (ret != 0)
+        {
+          printf("main: ERROR rmdir(%s) failed with errno=%d\n",
+                     g_testdir1, *get_errno_ptr());
+        }
+
+      /* Unmount the file system */
+
+      printf("main: Try unmount(%s)\n", g_target);
+
       ret = umount(g_target);
-      printf("main: umount() returned %d\n", ret);
+      if (ret != 0)
+        {
+          printf("main: ERROR umount() failed, errno %d\n", *get_errno_ptr());
+        }
     }
   
   fflush(stdout);
diff --git a/fs/fs_fat32.c b/fs/fs_fat32.c
index 81992e72d0d30f47308290ef46f4699a13d0eb9c..d0561f3800d3ffa2dad2a05c54b6cf1863399a5c 100644
--- a/fs/fs_fat32.c
+++ b/fs/fs_fat32.c
@@ -73,7 +73,7 @@
  * Private Function Prototypes
  ****************************************************************************/
 
-static int     fat_open(FAR struct file *filp, const char *rel_path,
+static int     fat_open(FAR struct file *filp, const char *relpath,
                         int oflags, mode_t mode);
 static int     fat_close(FAR struct file *filp);
 static ssize_t fat_read(FAR struct file *filp, char *buffer, size_t buflen);
@@ -86,10 +86,10 @@ static int     fat_sync(FAR struct file *filp);
 static int     fat_bind(FAR struct inode *blkdriver, const void *data,
                         void **handle);
 static int     fat_unbind(void *handle);
-static int     fat_unlink(struct inode *mountpt, const char *rel_path);
-static int     fat_mkdir(struct inode *mountpt, const char *rel_path,
+static int     fat_unlink(struct inode *mountpt, const char *relpath);
+static int     fat_mkdir(struct inode *mountpt, const char *relpath,
                          mode_t mode);
-static int     fat_rmdir(struct inode *mountpt, const char *rel_path);
+static int     fat_rmdir(struct inode *mountpt, const char *relpath);
 static int     fat_rename(struct inode *mountpt, const char *old_relpath,
                           const char *new_relpath);
 
@@ -120,6 +120,7 @@ const struct mountpt_operations fat_operations =
   fat_unbind,
   fat_unlink,
   fat_mkdir,
+  fat_rmdir,
   fat_rename
 };
 
@@ -131,7 +132,7 @@ const struct mountpt_operations fat_operations =
  * Name: fat_open
  ****************************************************************************/
 
-static int fat_open(FAR struct file *filp, const char *rel_path,
+static int fat_open(FAR struct file *filp, const char *relpath,
                     int oflags, mode_t mode)
 {
   struct fat_dirinfo_s  dirinfo;
@@ -165,13 +166,12 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
   /* Initialize the directory info structure */
 
   memset(&dirinfo, 0, sizeof(struct fat_dirinfo_s));
-  dirinfo.fs = fs;
 
   /* Locate the directory entry for this path */
 
-  ret = fat_finddirentry(&dirinfo, rel_path);
+  ret = fat_finddirentry(fs, &dirinfo, relpath);
 
-  /* Three possibililities: (1) a node exists for the rel_path and
+  /* Three possibililities: (1) a node exists for the relpath and
    * dirinfo describes the directory entry of the entity, (2) the
    * node does not exist, or (3) some error occurred.
    */
@@ -206,7 +206,7 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
       /* Check if the caller has sufficient privileges to open the file */
 
       readonly = ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_READONLY) != 0);
-      if (((oflags && O_WRONLY) != 0) && readonly)
+      if (((oflags & O_WRONLY) != 0) && readonly)
         {
           ret = -EACCES;
           goto errout_with_semaphore;
@@ -236,7 +236,7 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
     {
       /* The file does not exist.  Were we asked to create it? */
 
-      if ((oflags && O_CREAT) == 0)
+      if ((oflags & O_CREAT) == 0)
         {
           /* No.. then we fail with -ENOENT */
           ret = -ENOENT;
@@ -303,7 +303,7 @@ static int fat_open(FAR struct file *filp, const char *rel_path,
 
   /* In write/append mode, we need to set the file pointer to the end of the file */
 
-  if ((oflags && (O_APPEND|O_WRONLY)) == (O_APPEND|O_WRONLY))
+  if ((oflags & (O_APPEND|O_WRONLY)) == (O_APPEND|O_WRONLY))
     {
         ff->ff_position   = ff->ff_size;
     }
@@ -1320,7 +1320,7 @@ static int fat_unbind(void *handle)
  *
  ****************************************************************************/
 
-static int fat_unlink(struct inode *mountpt, const char *rel_path)
+static int fat_unlink(struct inode *mountpt, const char *relpath)
 {
   struct fat_mountpt_s *fs;
   int                   ret;
@@ -1337,15 +1337,20 @@ static int fat_unlink(struct inode *mountpt, const char *rel_path)
 
   fat_semtake(fs);
   ret = fat_checkmount(fs);
-  if (ret != OK)
+  if (ret == OK)
     {
-      goto errout_with_semaphore;
-    }
+      /* If the file is open, the correct behavior is to remove the file
+       * name, but to keep the file cluster chain in place until the last
+       * open reference to the file is closed.
+       */
 
-#warning "fat_unlink is not implemented"
-  ret = -ENOSYS;
+#warning "Need to defer deleting cluster chain if the file is open"
+
+      /* Remove the file */
+
+      ret = fat_remove(fs, relpath, FALSE);
+    }
 
- errout_with_semaphore:
   fat_semgive(fs);
   return ret;
 }
@@ -1357,7 +1362,7 @@ static int fat_unlink(struct inode *mountpt, const char *rel_path)
  *
  ****************************************************************************/
 
-static int fat_mkdir(struct inode *mountpt, const char *rel_path, mode_t mode)
+static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
 {
   struct fat_mountpt_s *fs;
   int                   ret;
@@ -1394,7 +1399,7 @@ static int fat_mkdir(struct inode *mountpt, const char *rel_path, mode_t mode)
  *
  ****************************************************************************/
 
-int fat_rmdir(struct inode *mountpt, const char *rel_path)
+int fat_rmdir(struct inode *mountpt, const char *relpath)
 {
   struct fat_mountpt_s *fs;
   int                   ret;
@@ -1411,15 +1416,20 @@ int fat_rmdir(struct inode *mountpt, const char *rel_path)
 
   fat_semtake(fs);
   ret = fat_checkmount(fs);
-  if (ret != OK)
+  if (ret == OK)
     {
-      goto errout_with_semaphore;
-    }
+      /* If the directory is open, the correct behavior is to remove the directory
+       * name, but to keep the directory cluster chain in place until the last
+       * open reference to the directory is closed.
+       */
 
-#warning "fat_rmdir is not implemented"
-  ret = -ENOSYS;
+#warning "Need to defer deleting cluster chain if the directory is open"
+
+      /* Remove the directory */
+
+      ret = fat_remove(fs, relpath, TRUE);
+    }
 
- errout_with_semaphore:
   fat_semgive(fs);
   return ret;
 }
diff --git a/fs/fs_fat32.h b/fs/fs_fat32.h
index 9e10cd7d8acbb2e7496f420d38431feb6bb0ea31..e8edd14c7dfa5f4a7face389d2772ae943c5d4b3 100644
--- a/fs/fs_fat32.h
+++ b/fs/fs_fat32.h
@@ -488,7 +488,6 @@ struct fat_file_s
 
 struct fat_dirinfo_s
 {
-  struct fat_mountpt_s *fs;        /* Pointer to the parent mountpoint */
   ubyte    fd_name[8+3];           /* Filename -- directory format*/
 #ifdef CONFIG_FAT_LCNAMES
   ubyte    fd_ntflags;             /* NTRes lower case flags */
@@ -557,15 +556,17 @@ EXTERN sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster);
 
 /* Help for traverseing directory trees */
 
-EXTERN int    fat_nextdirentry(struct fat_dirinfo_s *dirinfo);
-EXTERN int    fat_finddirentry(struct fat_dirinfo_s *dirinfo, const char *path);
+EXTERN int    fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
+EXTERN int    fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
+                               const char *path);
 
-/* File creation helpers */
+/* File creation and removal helpers */
 
 EXTERN int    fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
 EXTERN int    fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
+EXTERN int    fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory);
 
-/* Mountpoint and fFile buffer cache (for partial sector accesses) */
+/* Mountpoint and file buffer cache (for partial sector accesses) */
 
 EXTERN int    fat_fscacheread(struct fat_mountpt_s *fs, size_t sector);
 EXTERN int    fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff);
diff --git a/fs/fs_fat32util.c b/fs/fs_fat32util.c
index 826d13bec314f70082b1208ce1234b4fe647da5a..eb7981a5609ddf3fc7ff98daf69dd98a5ba5ac27 100644
--- a/fs/fs_fat32util.c
+++ b/fs/fs_fat32util.c
@@ -471,7 +471,7 @@ static int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *
           return OK;
         }
 
-      ret = fat_nextdirentry(dirinfo);
+      ret = fat_nextdirentry(fs, dirinfo);
       if (ret < 0)
         {
           return ret;
@@ -1583,9 +1583,8 @@ sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster)
  *
  ****************************************************************************/
 
-int fat_nextdirentry(struct fat_dirinfo_s *dirinfo)
+int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
 {
-  struct fat_mountpt_s *fs = dirinfo->fs;
   unsigned int cluster;
   unsigned int ndx;
 
@@ -1674,9 +1673,9 @@ int fat_nextdirentry(struct fat_dirinfo_s *dirinfo)
  *
  ****************************************************************************/
 
-int fat_finddirentry(struct fat_dirinfo_s *dirinfo, const char *path)
+int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
+                     const char *path)
 {
-  struct fat_mountpt_s *fs = dirinfo->fs;
   size_t cluster;
   ubyte *direntry = NULL;
   char terminator;
@@ -1778,7 +1777,7 @@ int fat_finddirentry(struct fat_dirinfo_s *dirinfo, const char *path)
 
           /* No... get the next directory index and try again */
 
-          if (fat_nextdirentry(dirinfo) != OK)
+          if (fat_nextdirentry(fs, dirinfo) != OK)
             {
               return -ENOENT;
             }
@@ -1935,6 +1934,184 @@ int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
   return OK;
 }
 
+/****************************************************************************
+ * Name: fat_remove
+ *
+ * Desciption: Remove a directory or file from the file system.  This
+ *   implements both rmdir() and unlink().
+ *
+ ****************************************************************************/
+
+int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
+{
+  struct fat_dirinfo_s dirinfo;
+  uint32  dircluster;
+  size_t  dirsector;
+  int     ret;
+
+  /* Find the directory entry referring to the entry to be deleted */
+
+  ret = fat_finddirentry(fs, &dirinfo, relpath);
+  if (ret != OK)
+    {
+      /* No such path */
+
+      return -ENOENT;
+    }
+
+  /* Check if this is a FAT12/16 root directory */
+
+  if (dirinfo.fd_entry == NULL)
+    {
+      /* The root directory cannot be removed */
+
+      return -EPERM;
+    }
+
+  /* The object has to have write access to be deleted */
+
+  if ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_READONLY) != 0)
+    {
+      /* It is a read-only entry */
+
+      return -EACCES;
+    }
+
+  /* Get the directory sector and cluster containing the
+   * entry to be deleted
+   */
+
+  dirsector  = fs->fs_currentsector;
+  dircluster =
+      ((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
+      DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
+
+  /* Is this entry a directory? */
+
+  if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY)
+    {
+      /* It is a sub-directory. Check if we are be asked to remove
+       * a directory or a file.
+       */
+
+      if (!directory)
+        {
+          /* We are asked to delete a file */
+
+          return -EISDIR;
+        }
+
+      /* We are asked to delete a directory. Check if this
+       * sub-directory is empty
+       */
+
+      dirinfo.fd_currcluster = dircluster;
+      dirinfo.fd_currsector  = fat_cluster2sector(fs, dircluster);
+      dirinfo.fd_index       = 2;
+
+      /* Loop until either (1) an entry is found in the directory
+       * (error), (2) the directory is found to be empty, or (3) some
+       * error occurs.
+       */
+
+      for (;;)
+        {
+          unsigned int subdirindex;
+          ubyte       *subdirentry;
+
+          /* Make sure that the sector containing the of the
+           * subdirectory sector is in the cache
+           */
+
+          ret = fat_fscacheread(fs, dirinfo.fd_currsector);
+          if (ret < 0)
+            {
+              return ret;
+            }
+
+          /* Get a reference to the next entry in the directory */
+
+          subdirindex = (dirinfo.fd_index & DIRSEC_NDXMASK(fs)) * 32;
+          subdirentry = &fs->fs_buffer[subdirindex];
+
+          /* Is this the last entry in the direcory? */
+
+          if (subdirentry[DIR_NAME] == DIR0_ALLEMPTY)
+            {
+              /* Yes then the directory is empty.  Break out of the
+               * loop and delete the directory.
+               */
+
+              break;
+            }
+
+          /* Check if the next entry refers to a file or directory */
+
+          if (subdirentry[DIR_NAME] != DIR0_EMPTY &&
+              !(DIR_GETATTRIBUTES(subdirentry) & FATATTR_VOLUMEID))
+            {
+              /* The directory is not empty */
+
+              return -ENOTEMPTY;
+            }
+
+          /* Get the next directgory entry */
+
+          ret = fat_nextdirentry(fs, &dirinfo);
+          if (ret < 0)
+            {
+              return ret;
+            }
+        }
+    }
+  else
+    {
+      /* It is a file. Check if we are be asked to remove a directory
+       * or a file.
+       */
+
+      if (directory)
+        {
+          /* We are asked to remove a directory */
+
+          return -ENOTDIR;
+        }
+    }
+
+  /* Make sure that the directory containing the entry to be deleted is
+   * in the cache.
+   */
+
+  ret = fat_fscacheread(fs, dirsector);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Mark the directory entry 'deleted' */
+
+  dirinfo.fd_entry[DIR_NAME] = DIR0_EMPTY;
+  fs->fs_dirty = TRUE;
+
+  /* And remove the cluster chain making up the subdirectory */
+
+  ret = fat_removechain(fs, dircluster);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Update the FSINFO sector (FAT32) */
+
+  ret = fat_updatefsinfo(fs);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  return OK;
+}
+
 /****************************************************************************
  * Name: fat_fscacheread
  *
@@ -2092,7 +2269,7 @@ int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff)
  * Name: fat_updatefsinfo
  *
  * Desciption: Flush evertyhing buffered for the mountpoint and update
- *  the FSINFO sector, if appropriate
+ *   the FSINFO sector, if appropriate
  *
  ****************************************************************************/
 
diff --git a/include/nuttx/fs.h b/include/nuttx/fs.h
index 639f688567b9e321bbffb1071fc04a777dc4c872..42ba19661777ed0db1a5e1ac9b4e6fac839c88b7 100644
--- a/include/nuttx/fs.h
+++ b/include/nuttx/fs.h
@@ -122,7 +122,7 @@ struct mountpt_operations
    * information to manage privileges.
    */
 
-  int     (*open)(FAR struct file *filp, const char *rel_path,
+  int     (*open)(FAR struct file *filp, const char *relpath,
                   int oflags, mode_t mode);
 
   /* The following methods must be identical in signature and position because
@@ -150,10 +150,10 @@ struct mountpt_operations
   int     (*bind)(FAR struct inode *blkdriver, const void *data, void **handle);
   int     (*unbind)(void *handle);
 
-  int     (*unlink)(struct inode *mountpt, const char *rel_path);
-  int     (*mkdir)(struct inode *mountpt, const char *rel_path, mode_t mode);
-  int     (*rmdir)(struct inode *mountpt, const char *rel_path);
-  int     (*rename)(struct inode *mountpt, const char *old_relpath, const char *new_relpath);
+  int     (*unlink)(struct inode *mountpt, const char *relpath);
+  int     (*mkdir)(struct inode *mountpt, const char *relpath, mode_t mode);
+  int     (*rmdir)(struct inode *mountpt, const char *relpath);
+  int     (*rename)(struct inode *mountpt, const char *oldrelpath, const char *newrelpath);
 
   /* NOTE:  More operations will be needed here to support:  disk usage stats
    * file stat(), file attributes, file truncation, etc.