summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-21 17:17:42 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-21 17:17:42 +0000
commit2bb67b254657c5707557082da0b23449b8309c72 (patch)
tree12e921379a6979b29804391ac650ed42c4c12fd1
parentd7d1d7f99d0cd4549f676cf9e450124c9c4170cb (diff)
downloadnuttx-2bb67b254657c5707557082da0b23449b8309c72.tar.gz
nuttx-2bb67b254657c5707557082da0b23449b8309c72.tar.bz2
nuttx-2bb67b254657c5707557082da0b23449b8309c72.zip
Add FAT rmdir and unlink
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@247 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/Documentation/NuttX.html54
-rw-r--r--nuttx/arch/sim/src/up_deviceimage.c6
-rw-r--r--nuttx/examples/mount/mount_main.c145
-rw-r--r--nuttx/fs/fs_fat32.c62
-rw-r--r--nuttx/fs/fs_fat32.h11
-rw-r--r--nuttx/fs/fs_fat32util.c191
-rw-r--r--nuttx/include/nuttx/fs.h10
8 files changed, 430 insertions, 51 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index c6d46b359..060eb3f01 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/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/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 726a5a5c5..49db96df2 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/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/nuttx/arch/sim/src/up_deviceimage.c b/nuttx/arch/sim/src/up_deviceimage.c
index 9a28f4edd..70dfc9cab 100644
--- a/nuttx/arch/sim/src/up_deviceimage.c
+++ b/nuttx/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/nuttx/examples/mount/mount_main.c b/nuttx/examples/mount/mount_main.c
index 09dc8e189..75cc3c2ce 100644
--- a/nuttx/examples/mount/mount_main.c
+++ b/nuttx/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/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c
index 81992e72d..d0561f380 100644
--- a/nuttx/fs/fs_fat32.c
+++ b/nuttx/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/nuttx/fs/fs_fat32.h b/nuttx/fs/fs_fat32.h
index 9e10cd7d8..e8edd14c7 100644
--- a/nuttx/fs/fs_fat32.h
+++ b/nuttx/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/nuttx/fs/fs_fat32util.c b/nuttx/fs/fs_fat32util.c
index 826d13bec..eb7981a56 100644
--- a/nuttx/fs/fs_fat32util.c
+++ b/nuttx/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;
}
@@ -1936,6 +1935,184 @@ int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
}
/****************************************************************************
+ * 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
*
* Desciption: Read the specified sector into the sector cache, flushing any
@@ -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/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h
index 639f68856..42ba19661 100644
--- a/nuttx/include/nuttx/fs.h
+++ b/nuttx/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.