Finish FAT directory operations; add option to disable mountpoints; fix ARM compile errors

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@252 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2007-05-26 19:22:34 +00:00
parent 48b2897974
commit 84e1cf94cf
35 changed files with 630 additions and 254 deletions
+4
View File
@@ -143,5 +143,9 @@
* Added unlink(), mkdir(), rmdir(), and rename() * Added unlink(), mkdir(), rmdir(), and rename()
* Fixed several serious FAT errors with oflags handling (&& instead of &) * Fixed several serious FAT errors with oflags handling (&& instead of &)
* Added FAT support for unlink(), mkdir(), rmdir(), and rename * Added FAT support for unlink(), mkdir(), rmdir(), and rename
* Added FAT support for opendir(), closedir(), readdir(), seekdir(),
telldir(), rewindir().
* Fixed ARM compilation errors introduced in 1.2.5 (that is what I get
for only testing on the simulation).
* Started m68322 * Started m68322
+5 -1
View File
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4"> <tr align="center" bgcolor="#e4e4e4">
<td> <td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1> <h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: May 21, 2007</p> <p>Last Updated: May 26, 2007</p>
</td> </td>
</tr> </tr>
</table> </table>
@@ -574,6 +574,10 @@ Other memory:
* Added unlink(), mkdir(), rmdir(), and rename() * Added unlink(), mkdir(), rmdir(), and rename()
* Fixed several serious FAT errors with oflags handling (&& instead of &) * Fixed several serious FAT errors with oflags handling (&& instead of &)
* Added FAT support for unlink(), mkdir(), rmdir(), and rename() * Added FAT support for unlink(), mkdir(), rmdir(), and rename()
* Added FAT support for opendir(), closedir(), readdir(), seekdir(),
telldir(), rewindir().
* Fixed ARM compilation errors introduced in 1.2.5 (that is what I get
for only testing on the simulation).
* Started m68322 * Started m68322
</pre></ul> </pre></ul>
+4 -3
View File
@@ -16,7 +16,7 @@
</b></big> </b></big>
<p><small>by</small></p> <p><small>by</small></p>
<p>Gregory Nutt</p> <p>Gregory Nutt</p>
<p><small>Last Update: April 30, 2007</small></p> <p><small>Last Update: May 26, 2007</small></p>
</center> </center>
<center><h1>Table of Contents</h1></center> <center><h1>Table of Contents</h1></center>
@@ -1211,8 +1211,9 @@ The system can be re-made subsequently by just typing <code>make</code>.
</ul> </ul>
<ul> <ul>
<code>CONFIG_DISABLE_CLOCK</code>, <code>CONFI_DISABLE_POSIX_TIMERS</code>, <code>CONFIG_DISABLE_PTHREAD</code>, <code>CONFIG_DISABLE_CLOCK</code>, <code>CONFI_DISABLE_POSIX_TIMERS</code>,
<code>CONFIG_DISABLE_SIGNALS</code>, <code>CONFIG_DISABLE_MQUEUE</code>, <code>CONFIG_DISABLE_PTHREAD</code>, <code>CONFIG_DISABLE_SIGNALS</code>,
<code>CONFIG_DISABLE_MQUEUE</code>, <code>CONFIG_DISABLE_MOUNTPOUNT</code>
</ul> </ul>
<h2>Miscellaneous libc settings</h2> <h2>Miscellaneous libc settings</h2>
+1
View File
@@ -43,6 +43,7 @@
#include <debug.h> #include <debug.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include "os_internal.h" #include "os_internal.h"
#include "clock_internal.h"
#include "up_internal.h" #include "up_internal.h"
/************************************************************ /************************************************************
+1 -1
View File
@@ -159,7 +159,7 @@ defconfig -- This is a configuration file similar to the Linux
up waiting tasks. up waiting tasks.
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_POSIX_TIMERS, CONFIG_DISABLE_PTHREAD. CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_POSIX_TIMERS, CONFIG_DISABLE_PTHREAD.
CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE, CONFIG_DISABLE_MOUNTPOUNT
Misc libc settings Misc libc settings
+1
View File
@@ -157,6 +157,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n CONFIG_DISABLE_MQUEUE=n
CONFIG_DISABLE_MOUNTPOINT=y
# #
# Misc libc settings # Misc libc settings
+1
View File
@@ -146,6 +146,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n CONFIG_DISABLE_MQUEUE=n
CONFIG_DISABLE_MOUNTPOINT=y
# #
# Misc libc settings # Misc libc settings
+1
View File
@@ -170,6 +170,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n CONFIG_DISABLE_MQUEUE=n
CONFIG_DISABLE_MOUNTPOINT=y
# #
# Misc libc settings # Misc libc settings
+1
View File
@@ -155,6 +155,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n CONFIG_DISABLE_MQUEUE=n
CONFIG_DISABLE_MOUNTPOINT=y
# #
# Misc libc settings # Misc libc settings
+1
View File
@@ -143,6 +143,7 @@ CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_DISABLE_PTHREAD=y CONFIG_DISABLE_PTHREAD=y
CONFIG_DISABLE_SIGNALS=y CONFIG_DISABLE_SIGNALS=y
CONFIG_DISABLE_MQUEUE=y CONFIG_DISABLE_MQUEUE=y
CONFIG_DISABLE_MOUNTPOINT=y
# #
# Misc libc settings # Misc libc settings
+1
View File
@@ -111,6 +111,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n CONFIG_DISABLE_MQUEUE=n
CONFIG_DISABLE_MOUNTPOINT=n
# #
# Misc libc settings # Misc libc settings
+5 -2
View File
@@ -45,12 +45,15 @@ CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \
fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_fsync.c fs_files.c \ fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_fsync.c fs_files.c \
fs_inode.c fs_inodefind.c fs_inodereserve.c \ fs_inode.c fs_inodefind.c fs_inodereserve.c \
fs_inoderemove.c fs_registerdriver.c fs_unregisterdriver.c \ fs_inoderemove.c fs_registerdriver.c fs_unregisterdriver.c \
fs_registerblockdriver.c fs_unregisterblockdriver.c \ fs_inodeaddref.c fs_inoderelease.c
ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
CSRCS += fs_registerblockdriver.c fs_unregisterblockdriver.c \
fs_mount.c fs_umount.c fs_unlink.c fs_mkdir.c fs_rmdir.c \ fs_mount.c fs_umount.c fs_unlink.c fs_mkdir.c fs_rmdir.c \
fs_rename.c fs_inodeaddref.c fs_inoderelease.c fs_rename.c
ifeq ($(CONFIG_FS_FAT),y) ifeq ($(CONFIG_FS_FAT),y)
CSRCS += fs_fat32.c fs_fat32util.c CSRCS += fs_fat32.c fs_fat32util.c
endif endif
endif
COBJS = $(CSRCS:.c=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS) SRCS = $(ASRCS) $(CSRCS)
+27 -10
View File
@@ -76,8 +76,12 @@
int closedir(FAR DIR *dirp) int closedir(FAR DIR *dirp)
{ {
struct internal_dir_s *idir = (struct internal_dir_s *)dirp; struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
#ifndef CONFIG_DISABLE_MOUNTPOUNT
struct inode *inode;
#endif
int ret;
if (!idir || !idir->root) if (!idir || !idir->fd_root)
{ {
*get_errno_ptr() = EBADF; *get_errno_ptr() = EBADF;
return ERROR; return ERROR;
@@ -87,31 +91,44 @@ int closedir(FAR DIR *dirp)
* inode we have open. * inode we have open.
*/ */
if (IS_MOUNTPT_INODE(idir->root)) #ifndef CONFIG_DISABLE_MOUNTPOUNT
inode = idir->fd_root;
if (INODE_IS_MOUNTPT(inode))
{ {
/* The node is a file system mointpoint */ /* The node is a file system mointpoint. Verify that the mountpoint
* supports the closedir() method (not an error if it does not)
*/
#warning "Mountpoint support not implemented" if (inode->u.i_mops && inode->u.i_mops->closedir)
*get_errno_ptr() = ENOSYS; {
return ERROR; /* Perform the closedir() operation */
ret = inode->u.i_mops->closedir(inode, idir);
if (ret < 0)
{
*get_errno_ptr() = -ret;
return ERROR;
}
}
} }
else else
#endif
{ {
/* The node is part of the root psuedo file system, release /* The node is part of the root psuedo file system, release
* our contained reference to the 'next' inode. * our contained reference to the 'next' inode.
*/ */
if (idir->u.psuedo.next) if (idir->u.psuedo.fd_next)
{ {
inode_release(idir->u.psuedo.next); inode_release(idir->u.psuedo.fd_next);
} }
} }
/* Release our references on the contained 'root' inode */ /* Release our references on the contained 'root' inode */
if (idir->root) if (idir->fd_root)
{ {
inode_release(idir->root); inode_release(idir->fd_root);
} }
/* Then release the container */ /* Then release the container */
+174 -11
View File
@@ -59,7 +59,8 @@
#include "fs_internal.h" #include "fs_internal.h"
#include "fs_fat32.h" #include "fs_fat32.h"
#if CONFIG_FS_FAT #ifdef CONFIG_FS_FAT
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -85,6 +86,8 @@ static int fat_sync(FAR struct file *filp);
static int fat_opendir(struct inode *mountpt, const char *relpath, static int fat_opendir(struct inode *mountpt, const char *relpath,
struct internal_dir_s *dir); struct internal_dir_s *dir);
static int fat_readdir(struct inode *mountpt, struct internal_dir_s *dir);
static int fat_rewinddir(struct inode *mountpt, struct internal_dir_s *dir);
static int fat_bind(FAR struct inode *blkdriver, const void *data, static int fat_bind(FAR struct inode *blkdriver, const void *data,
void **handle); void **handle);
@@ -120,6 +123,9 @@ const struct mountpt_operations fat_operations =
fat_sync, fat_sync,
fat_opendir, fat_opendir,
NULL,
fat_readdir,
fat_rewinddir,
fat_bind, fat_bind,
fat_unbind, fat_unbind,
@@ -296,7 +302,7 @@ static int fat_open(FAR struct file *filp, const char *relpath,
/* Save information that can be used later to recover the directory entry */ /* Save information that can be used later to recover the directory entry */
ff->ff_dirsector = fs->fs_currentsector; ff->ff_dirsector = fs->fs_currentsector;
ff->ff_dirindex = dirinfo.fd_index; ff->ff_dirindex = dirinfo.dir.fd_index;
/* File cluster/size info */ /* File cluster/size info */
@@ -1248,10 +1254,10 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct intern
{ {
/* Handler the FAT12/16 root directory */ /* Handler the FAT12/16 root directory */
dir->u.fat.startcluster = 0; dir->u.fat.fd_startcluster = 0;
dir->u.fat.currcluster = 0; dir->u.fat.fd_currcluster = 0;
dir->u.fat.currsector = fs->fs_rootbase; dir->u.fat.fd_currsector = fs->fs_rootbase;
dir->u.fat.dirindex = 2; dir->u.fat.fd_index = 2;
} }
/* This is not the root directory. Verify that it is some kind of directory */ /* This is not the root directory. Verify that it is some kind of directory */
@@ -1266,12 +1272,168 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct intern
{ {
/* The entry is a directory */ /* The entry is a directory */
dir->u.fat.startcluster = dir->u.fat.fd_startcluster =
((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) | ((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
DIR_GETFSTCLUSTLO(dirinfo.fd_entry); DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
dir->u.fat.currcluster = dir->u.fat.startcluster; dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
dir->u.fat.currsector = fat_cluster2sector(fs, dir->u.fat.currcluster); dir->u.fat.fd_currsector = fat_cluster2sector(fs, dir->u.fat.fd_currcluster);
dir->u.fat.dirindex = 2; dir->u.fat.fd_index = 2;
}
fat_semgive(fs);
return OK;
errout_with_semaphore:
fat_semgive(fs);
return ERROR;
}
/****************************************************************************
* Name: fat_readdir
*
* Description: Read the next directory entry
*
****************************************************************************/
static int fat_readdir(struct inode *mountpt, struct internal_dir_s *dir)
{
struct fat_mountpt_s *fs;
unsigned int dirindex;
ubyte *direntry;
ubyte ch;
ubyte attribute;
int ret;
/* Sanity checks */
DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
/* Recover our private data from the inode instance */
fs = mountpt->i_private;
/* Make sure that the mount is still healthy */
fat_semtake(fs);
ret = fat_checkmount(fs);
if (ret != OK)
{
goto errout_with_semaphore;
}
/* Read the next directory entry */
dir->fd_dir.d_name[0] = '\0';
while (dir->u.fat.fd_currsector && dir->fd_dir.d_name[0] == '\0')
{
ret = fat_fscacheread(fs, dir->u.fat.fd_currsector);
if ( ret < 0)
{
goto errout_with_semaphore;
}
/* Get a reference to the current directory entry */
dirindex = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * 32;
direntry = &fs->fs_buffer[dirindex];
/* Has it reached to end of the directory */
ch = *direntry;
if (ch == DIR0_ALLEMPTY)
{
/* We signal the end of the directory by returning the
* special error -ENOENT
*/
ret = -ENOENT;
goto errout_with_semaphore;
}
/* No, is the current entry a valid entry? */
attribute = DIR_GETATTRIBUTES(direntry);
if (ch != DIR0_EMPTY && (attribute & FATATTR_VOLUMEID) == 0)
{
/* Yes.. get the name from the directory info */
(void)fat_dirname2path(dir->fd_dir.d_name, direntry);
/* And the file type */
if ((attribute & FATATTR_DIRECTORY) == 0)
{
dir->fd_dir.d_type = DTYPE_FILE;
}
else
{
dir->fd_dir.d_type = DTYPE_DIRECTORY;
}
}
/* Set up the next directory index */
if (fat_nextdirentry(fs, &dir->u.fat) != OK)
{
dir->u.fat.fd_currsector = 0;
}
}
fat_semgive(fs);
return OK;
errout_with_semaphore:
fat_semgive(fs);
return ERROR;
}
/****************************************************************************
* Name: fat_rewindir
*
* Description: Reset directory read to the first entry
*
****************************************************************************/
static int fat_rewinddir(struct inode *mountpt, struct internal_dir_s *dir)
{
struct fat_mountpt_s *fs;
int ret;
/* Sanity checks */
DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
/* Recover our private data from the inode instance */
fs = mountpt->i_private;
/* Make sure that the mount is still healthy */
fat_semtake(fs);
ret = fat_checkmount(fs);
if (ret != OK)
{
goto errout_with_semaphore;
}
/* Check if this is the root directory */
if (dir->u.fat.fd_startcluster == 0)
{
/* Handler the FAT12/16 root directory */
dir->u.fat.fd_currcluster = 0;
dir->u.fat.fd_currsector = fs->fs_rootbase;
dir->u.fat.fd_index = 2;
}
/* This is not the root directory */
else
{
dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
dir->u.fat.fd_currsector = fat_cluster2sector(fs, dir->u.fat.fd_currcluster);
dir->u.fat.fd_index = 2;
} }
fat_semgive(fs); fat_semgive(fs);
@@ -1589,7 +1751,7 @@ static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
DIR_PUTFSTCLUSTHI(direntry, dircluster >> 16); DIR_PUTFSTCLUSTHI(direntry, dircluster >> 16);
DIR_PUTFSTCLUSTLO(direntry, dircluster); DIR_PUTFSTCLUSTLO(direntry, dircluster);
parentcluster = dirinfo.fd_startcluster; parentcluster = dirinfo.dir.fd_startcluster;
if (fs->fs_type != FSTYPE_FAT32 && parentcluster == fs->fs_rootbase) if (fs->fs_type != FSTYPE_FAT32 && parentcluster == fs->fs_rootbase)
{ {
parentcluster = 0; parentcluster = 0;
@@ -1833,4 +1995,5 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_FS_FAT */ #endif /* CONFIG_FS_FAT */
+4 -5
View File
@@ -492,10 +492,7 @@ struct fat_dirinfo_s
#ifdef CONFIG_FAT_LCNAMES #ifdef CONFIG_FAT_LCNAMES
ubyte fd_ntflags; /* NTRes lower case flags */ ubyte fd_ntflags; /* NTRes lower case flags */
#endif #endif
uint16 fd_index; /* Current index */ struct fs_fatdir_s dir; /* Used with opendir, readdir, etc. */
size_t fd_startcluster; /* Start cluster number */
size_t fd_currcluster; /* Current cluster number */
size_t fd_currsector; /* Current sector */
ubyte *fd_entry; /* A pointer to the raw 32-byte entry */ ubyte *fd_entry; /* A pointer to the raw 32-byte entry */
}; };
@@ -556,11 +553,13 @@ EXTERN sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster);
/* Help for traverseing directory trees */ /* Help for traverseing directory trees */
EXTERN int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo); EXTERN int fat_nextdirentry(struct fat_mountpt_s *fs, struct fs_fatdir_s *dir);
EXTERN int fat_finddirentry(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); const char *path);
EXTERN int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo); EXTERN int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
EXTERN int fat_dirname2path(char *path, ubyte *direntry);
/* File creation and removal helpers */ /* File creation and removal helpers */
EXTERN int fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo); EXTERN int fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
+149 -145
View File
@@ -57,7 +57,8 @@
#include "fs_internal.h" #include "fs_internal.h"
#include "fs_fat32.h" #include "fs_fat32.h"
#if CONFIG_FS_FAT #ifdef CONFIG_FS_FAT
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -252,113 +253,6 @@ static inline int fat_path2dirname(const char **path, struct fat_dirinfo_s *diri
return -EINVAL; return -EINVAL;
} }
/****************************************************************************
* Name: fat_dirname2path
*
* Desciption: Convert a filename in a raw directory entry into a user
* filename. This is essentially the inverse operation of that performed
* by fat_path2dirname. See that function for more details.
*
****************************************************************************/
static inline int fat_dirname2path(char *path, struct fat_dirinfo_s *dirinfo)
{
const unsigned char *direntry = dirinfo->fd_entry;
int ch;
int ndx;
/* Check if we will be doing upper to lower case conversions */
#ifdef CONFIG_FAT_LCNAMES
dirinfo->fd_ntflags = DIR_GETNTRES(direntry);
#endif
/* Get the 8-byte filename */
for (ndx = 0; ndx < 8; ndx++)
{
/* Get the next filename character from the directory entry */
ch = direntry[ndx];
/* Any space (or ndx==8) terminates the filename */
if (ch == ' ')
{
break;
}
/* In this version, we never write 0xe5 in the directoryfilenames
* (because we do not handle any character sets where 0xe5 is valid
* in a filaname), but we could encounted this in a filesystem
* written by some other system
*/
if (ndx == 0 && ch == DIR0_E5)
{
ch = 0xe5;
}
/* Check if we should perform upper to lower case conversion
* of the (whole) filename.
*/
#ifdef CONFIG_FAT_LCNAMES
if (dirinfo->fd_ntflags & FATNTRES_LCNAME && isupper(ch))
{
ch = tolower(ch);
}
#endif
/* Copy the next character into the filename */
*path++ = ch;
}
/* Check if there is an extension */
if (direntry[8] != ' ')
{
/* Yes, output the dot before the extension */
*path++ = '.';
/* Then output the (up to) 3 character extension */
for (ndx = 8; ndx < 11; ndx++)
{
/* Get the next extensions character from the directory entry */
ch = dirinfo->fd_name[ndx];
/* Any space (or ndx==11) terminates the extension */
if (ch == ' ')
{
break;
}
/* Check if we should perform upper to lower case conversion
* of the (whole) filename.
*/
#ifdef CONFIG_FAT_LCNAMES
if (ntflags & FATNTRES_LCEXT && isupper(ch))
{
ch = tolower(ch);
}
#endif
/* Copy the next character into the filename */
*path++ = ch;
}
}
/* Put a null terminator at the end of the filename */
*path = '\0';
return OK;
}
/**************************************************************************** /****************************************************************************
* Name: fat_checkfsinfo * Name: fat_checkfsinfo
* *
@@ -1412,14 +1306,14 @@ sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster)
* *
****************************************************************************/ ****************************************************************************/
int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo) int fat_nextdirentry(struct fat_mountpt_s *fs, struct fs_fatdir_s *dir)
{ {
unsigned int cluster; unsigned int cluster;
unsigned int ndx; unsigned int ndx;
/* Increment the index to the next 32-byte directory entry */ /* Increment the index to the next 32-byte directory entry */
ndx = dirinfo->fd_index + 1; ndx = dir->fd_index + 1;
/* Check if all of the directory entries in this sectory have /* Check if all of the directory entries in this sectory have
* been examined. * been examined.
@@ -1429,13 +1323,13 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{ {
/* Yes, then we will have to read the next sector */ /* Yes, then we will have to read the next sector */
dirinfo->fd_currsector++; dir->fd_currsector++;
/* For FAT12/16, the root directory is a group of sectors relative /* For FAT12/16, the root directory is a group of sectors relative
* to the first sector of the fat volume. * to the first sector of the fat volume.
*/ */
if (!dirinfo->fd_currcluster) if (!dir->fd_currcluster)
{ {
/* For FAT12/13, the boot record tells us number of 32-bit directories /* For FAT12/13, the boot record tells us number of 32-bit directories
* that are contained in the root directory. This should correspond to * that are contained in the root directory. This should correspond to
@@ -1470,7 +1364,7 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{ {
/* Get next cluster */ /* Get next cluster */
cluster = fat_getcluster(fs, dirinfo->fd_currcluster); cluster = fat_getcluster(fs, dir->fd_currcluster);
/* Check if a valid cluster was obtained. */ /* Check if a valid cluster was obtained. */
@@ -1482,15 +1376,15 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
/* Initialize for new cluster */ /* Initialize for new cluster */
dirinfo->fd_currcluster = cluster; dir->fd_currcluster = cluster;
dirinfo->fd_currsector = fat_cluster2sector(fs, cluster); dir->fd_currsector = fat_cluster2sector(fs, cluster);
} }
} }
} }
/* Save the new index into dirinfo->fd_currsector */ /* Save the new index into dir->fd_currsector */
dirinfo->fd_index = ndx; dir->fd_index = ndx;
return OK; return OK;
} }
@@ -1522,9 +1416,9 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
* the first cluster of the root directory. * the first cluster of the root directory.
*/ */
dirinfo->fd_startcluster = cluster; dirinfo->dir.fd_startcluster = cluster;
dirinfo->fd_currcluster = cluster; dirinfo->dir.fd_currcluster = cluster;
dirinfo->fd_currsector = fat_cluster2sector(fs, cluster); dirinfo->dir.fd_currsector = fat_cluster2sector(fs, cluster);
} }
else else
{ {
@@ -1532,14 +1426,14 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
* relative to the first sector of the fat volume. * relative to the first sector of the fat volume.
*/ */
dirinfo->fd_startcluster = 0; dirinfo->dir.fd_startcluster = 0;
dirinfo->fd_currcluster = 0; dirinfo->dir.fd_currcluster = 0;
dirinfo->fd_currsector = cluster; dirinfo->dir.fd_currsector = cluster;
} }
/* fd_index is the index into the current directory table */ /* fd_index is the index into the current directory table */
dirinfo->fd_index = 0; dirinfo->dir.fd_index = 0;
/* If no path was provided, then the root directory must be exactly /* If no path was provided, then the root directory must be exactly
* what the caller is looking for. * what the caller is looking for.
@@ -1577,7 +1471,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
{ {
/* Read the next sector into memory */ /* Read the next sector into memory */
ret = fat_fscacheread(fs, dirinfo->fd_currsector); ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@@ -1585,7 +1479,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* Get a pointer to the directory entry */ /* Get a pointer to the directory entry */
direntry = &fs->fs_buffer[DIRSEC_BYTENDX(fs, dirinfo->fd_index)]; direntry = &fs->fs_buffer[DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index)];
/* Check if we are at the end of the directory */ /* Check if we are at the end of the directory */
@@ -1606,7 +1500,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* No... get the next directory index and try again */ /* No... get the next directory index and try again */
if (fat_nextdirentry(fs, dirinfo) != OK) if (fat_nextdirentry(fs, &dirinfo->dir) != OK)
{ {
return -ENOENT; return -ENOENT;
} }
@@ -1646,9 +1540,9 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* The restart scanning at the new directory */ /* The restart scanning at the new directory */
dirinfo->fd_currcluster = dirinfo->fd_startcluster = cluster; dirinfo->dir.fd_currcluster = dirinfo->dir.fd_startcluster = cluster;
dirinfo->fd_currsector = fat_cluster2sector(fs, cluster); dirinfo->dir.fd_currsector = fat_cluster2sector(fs, cluster);
dirinfo->fd_index = 2; dirinfo->dir.fd_index = 2;
} }
} }
@@ -1670,21 +1564,21 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Re-initialize directory object */ /* Re-initialize directory object */
cluster = dirinfo->fd_startcluster; cluster = dirinfo->dir.fd_startcluster;
if (cluster) if (cluster)
{ {
/* Cluster chain can be extended */ /* Cluster chain can be extended */
dirinfo->fd_currcluster = cluster; dirinfo->dir.fd_currcluster = cluster;
dirinfo->fd_currsector = fat_cluster2sector(fs, cluster); dirinfo->dir.fd_currsector = fat_cluster2sector(fs, cluster);
} }
else else
{ {
/* Fixed size FAT12/16 root directory is at fixxed offset/size */ /* Fixed size FAT12/16 root directory is at fixxed offset/size */
dirinfo->fd_currsector = fs->fs_rootbase; dirinfo->dir.fd_currsector = fs->fs_rootbase;
} }
dirinfo->fd_index = 0; dirinfo->dir.fd_index = 0;
for (;;) for (;;)
{ {
@@ -1692,7 +1586,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Read the directory sector into fs_buffer */ /* Read the directory sector into fs_buffer */
ret = fat_fscacheread(fs, dirinfo->fd_currsector); ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@@ -1700,7 +1594,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Get a pointer to the entry at fd_index */ /* Get a pointer to the entry at fd_index */
dirindex = (dirinfo->fd_index & DIRSEC_NDXMASK(fs)) * 32; dirindex = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * 32;
direntry = &fs->fs_buffer[dirindex]; direntry = &fs->fs_buffer[dirindex];
/* Check if this directory entry is empty */ /* Check if this directory entry is empty */
@@ -1714,7 +1608,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
return OK; return OK;
} }
ret = fat_nextdirentry(fs, dirinfo); ret = fat_nextdirentry(fs, &dirinfo->dir);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@@ -1737,7 +1631,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Try to extend the cluster chain for this directory */ /* Try to extend the cluster chain for this directory */
cluster = fat_extendchain(fs, dirinfo->fd_currcluster); cluster = fat_extendchain(fs, dirinfo->dir.fd_currcluster);
if (cluster < 0) if (cluster < 0)
{ {
return cluster; return cluster;
@@ -1773,6 +1667,115 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
return OK; return OK;
} }
/****************************************************************************
* Name: fat_dirname2path
*
* Desciption: Convert a filename in a raw directory entry into a user
* filename. This is essentially the inverse operation of that performed
* by fat_path2dirname. See that function for more details.
*
****************************************************************************/
int fat_dirname2path(char *path, ubyte *direntry)
{
#ifdef CONFIG_FAT_LCNAMES
ubyte ntflags;
#endif
int ch;
int ndx;
/* Check if we will be doing upper to lower case conversions */
#ifdef CONFIG_FAT_LCNAMES
ntflags = DIR_GETNTRES(direntry);
#endif
/* Get the 8-byte filename */
for (ndx = 0; ndx < 8; ndx++)
{
/* Get the next filename character from the directory entry */
ch = direntry[ndx];
/* Any space (or ndx==8) terminates the filename */
if (ch == ' ')
{
break;
}
/* In this version, we never write 0xe5 in the directoryfilenames
* (because we do not handle any character sets where 0xe5 is valid
* in a filaname), but we could encounted this in a filesystem
* written by some other system
*/
if (ndx == 0 && ch == DIR0_E5)
{
ch = 0xe5;
}
/* Check if we should perform upper to lower case conversion
* of the (whole) filename.
*/
#ifdef CONFIG_FAT_LCNAMES
if (ntflags & FATNTRES_LCNAME && isupper(ch))
{
ch = tolower(ch);
}
#endif
/* Copy the next character into the filename */
*path++ = ch;
}
/* Check if there is an extension */
if (direntry[8] != ' ')
{
/* Yes, output the dot before the extension */
*path++ = '.';
/* Then output the (up to) 3 character extension */
for (ndx = 8; ndx < 11; ndx++)
{
/* Get the next extensions character from the directory entry */
ch = direntry[DIR_NAME + ndx];
/* Any space (or ndx==11) terminates the extension */
if (ch == ' ')
{
break;
}
/* Check if we should perform upper to lower case conversion
* of the (whole) filename.
*/
#ifdef CONFIG_FAT_LCNAMES
if (ntflags & FATNTRES_LCEXT && isupper(ch))
{
ch = tolower(ch);
}
#endif
/* Copy the next character into the filename */
*path++ = ch;
}
}
/* Put a null terminator at the end of the filename */
*path = '\0';
return OK;
}
/**************************************************************************** /****************************************************************************
* Name: fat_dirtruncate * Name: fat_dirtruncate
* *
@@ -1955,9 +1958,9 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
* sub-directory is empty * sub-directory is empty
*/ */
dirinfo.fd_currcluster = dircluster; dirinfo.dir.fd_currcluster = dircluster;
dirinfo.fd_currsector = fat_cluster2sector(fs, dircluster); dirinfo.dir.fd_currsector = fat_cluster2sector(fs, dircluster);
dirinfo.fd_index = 2; dirinfo.dir.fd_index = 2;
/* Loop until either (1) an entry is found in the directory /* Loop until either (1) an entry is found in the directory
* (error), (2) the directory is found to be empty, or (3) some * (error), (2) the directory is found to be empty, or (3) some
@@ -1973,7 +1976,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
* subdirectory sector is in the cache * subdirectory sector is in the cache
*/ */
ret = fat_fscacheread(fs, dirinfo.fd_currsector); ret = fat_fscacheread(fs, dirinfo.dir.fd_currsector);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@@ -1981,7 +1984,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
/* Get a reference to the next entry in the directory */ /* Get a reference to the next entry in the directory */
subdirindex = (dirinfo.fd_index & DIRSEC_NDXMASK(fs)) * 32; subdirindex = (dirinfo.dir.fd_index & DIRSEC_NDXMASK(fs)) * 32;
subdirentry = &fs->fs_buffer[subdirindex]; subdirentry = &fs->fs_buffer[subdirindex];
/* Is this the last entry in the direcory? */ /* Is this the last entry in the direcory? */
@@ -2007,7 +2010,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
/* Get the next directgory entry */ /* Get the next directgory entry */
ret = fat_nextdirentry(fs, &dirinfo); ret = fat_nextdirentry(fs, &dirinfo.dir);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@@ -2313,4 +2316,5 @@ int fat_updatefsinfo(struct fat_mountpt_s *fs)
return ret; return ret;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_FS_FAT */ #endif /* CONFIG_FS_FAT */
+2
View File
@@ -48,6 +48,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -137,4 +138,5 @@ int fsync(int fd)
return ERROR; return ERROR;
} }
#endif /* CONFIG_DISABLE_MOUNTPOINT */
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+31 -26
View File
@@ -73,10 +73,34 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* The internal representation of type DIR is just a /* The internal representation of type DIR is just a container for an inode
* container for an inode reference and a dirent structure. * reference, a position, a dirent structure, and file-system-specific
* information.
*
* For the root psuedo-file system, we need retain only the 'next' inode
* need for the next readdir() operation. We hold a reference on this
* inode so we know that it will persist until closedir is called.
*/ */
struct fs_psuedodir_s
{
struct inode *fd_next; /* The inode for the next call to readdir() */
};
#ifdef CONFIG_FS_FAT
/* For fat, we need to retun the start cluster, current cluster, current
* sector and current directory index.
*/
struct fs_fatdir_s
{
uint32 fd_startcluster; /* Start cluster number of the directory*/
uint32 fd_currcluster; /* Current cluster number being read*/
size_t fd_currsector; /* Current sector being read*/
unsigned int fd_index; /* Current index of the directory entry to read */
};
#endif
struct internal_dir_s struct internal_dir_s
{ {
/* This is the node that was opened by opendir. The type of the inode /* This is the node that was opened by opendir. The type of the inode
@@ -87,11 +111,11 @@ struct internal_dir_s
* closedir() is called (although inodes linked to this inode may change). * closedir() is called (although inodes linked to this inode may change).
*/ */
struct inode *root; struct inode *fd_root;
/* This keeps track of the current directory position for telldir */ /* This keeps track of the current directory position for telldir */
off_t position; off_t fd_position;
/* Retained control information depends on the type of file system that /* Retained control information depends on the type of file system that
* provides is provides the mountpoint. Ideally this information should * provides is provides the mountpoint. Ideally this information should
@@ -101,34 +125,15 @@ struct internal_dir_s
union union
{ {
/* For the root psuedo-file system, we need retain only the 'next' inode struct fs_psuedodir_s psuedo;
* need for the next readdir() operation. We hold a reference on this
* inode so we know that it will persist until closedir is called.
*/
struct
{
struct inode *next; /* The inode for the next call to readdir() */
} psuedo;
#ifdef CONFIG_FS_FAT #ifdef CONFIG_FS_FAT
/* For fat, we need to retun the start cluster, current cluster, current struct fs_fatdir_s fat;
* sector and current directory index.
*/
struct
{
uint32 startcluster; /* Starting cluster of directory */
uint32 currcluster; /* The current cluster being read */
size_t currsector; /* The current sector being read */
unsigned int dirindex; /* The next directory entry to read */
} fat;
#endif #endif
} u; } u;
/* In any event, this the actual struct dirent that is returned by readdir */ /* In any event, this the actual struct dirent that is returned by readdir */
struct dirent dir; /* Populated when readdir is called */ struct dirent fd_dir; /* Populated when readdir is called */
}; };
/**************************************************************************** /****************************************************************************
+2
View File
@@ -46,6 +46,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -130,4 +131,5 @@ int mkdir(const char *pathname, mode_t mode)
return ERROR; return ERROR;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+2
View File
@@ -46,6 +46,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/* At least one filesystem must be defined, or this file will not compile. /* At least one filesystem must be defined, or this file will not compile.
* It may be desire-able to make filesystems dynamically registered at * It may be desire-able to make filesystems dynamically registered at
@@ -272,4 +273,5 @@ int mount(const char *source, const char *target,
} }
#endif /* Need at least filesystem */ #endif /* Need at least filesystem */
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* Need file descriptor support */ #endif /* Need file descriptor support */
+2
View File
@@ -153,12 +153,14 @@ int open(const char *path, int oflags, ...)
ret = OK; ret = OK;
if (inode->u.i_ops->open) if (inode->u.i_ops->open)
{ {
#ifndef CONFIG_DISABLE_MOUNTPOUNT
if (INODE_IS_MOUNTPT(inode)) if (INODE_IS_MOUNTPT(inode))
{ {
ret = inode->u.i_mops->open((FAR struct file*)&list->fl_files[fd], ret = inode->u.i_mops->open((FAR struct file*)&list->fl_files[fd],
relpath, oflags, mode); relpath, oflags, mode);
} }
else else
#endif
{ {
ret = inode->u.i_ops->open((FAR struct file*)&list->fl_files[fd]); ret = inode->u.i_ops->open((FAR struct file*)&list->fl_files[fd]);
} }
+6 -4
View File
@@ -197,11 +197,12 @@ FAR DIR *opendir(const char *path)
* inode or a file system mountpoint. * inode or a file system mountpoint.
*/ */
dir->root = inode; /* Save the inode where we start */ dir->fd_root = inode; /* Save the inode where we start */
dir->position = 0; /* This is the position in the read stream */ dir->fd_position = 0; /* This is the position in the read stream */
/* Is this a not in the psuedo filesystem? */ /* Is this a not in the psuedo filesystem? */
#ifndef CONFIG_DISABLE_MOUNTPOUNT
if (INODE_IS_MOUNTPT(inode)) if (INODE_IS_MOUNTPT(inode))
{ {
/* The node is a file system mointpoint. Verify that the mountpoint /* The node is a file system mointpoint. Verify that the mountpoint
@@ -224,11 +225,12 @@ FAR DIR *opendir(const char *path)
} }
} }
else else
#endif
{ {
/* The node is part of the root psuedo file system */ /* The node is part of the root psuedo file system */
inode_addref(inode); /* Now we have two references on inode */ inode_addref(inode); /* Now we have two references on inode */
dir->u.psuedo.next = inode; /* This is the next node to use for readdir() */ dir->u.psuedo.fd_next = inode; /* This is the next node to use for readdir() */
} }
return ((DIR*)dir); return ((DIR*)dir);
+65 -25
View File
@@ -53,52 +53,59 @@
* Name: readpsuedodir * Name: readpsuedodir
************************************************************/ ************************************************************/
static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir) #if CONFIG_NFILE_DESCRIPTORS > 0
static inline int readpsuedodir(struct internal_dir_s *idir)
{ {
FAR struct inode *prev; FAR struct inode *prev;
/* Check if we are at the end of the list */ /* Check if we are at the end of the list */
if (!idir->u.psuedo.next) if (!idir->u.psuedo.fd_next)
{ {
return NULL; /* End of file and error conditions are not distinguishable
* with readdir. Here we return -ENOENT to signal the end
* of the directory.
*/
return -ENOENT;
} }
/* Copy the inode name into the dirent structure */ /* Copy the inode name into the dirent structure */
strncpy(idir->dir.d_name, idir->u.psuedo.next->i_name, NAME_MAX+1); strncpy(idir->fd_dir.d_name, idir->u.psuedo.fd_next->i_name, NAME_MAX+1);
/* If the node has file operations, we will say that it is /* If the node has file operations, we will say that it is
* a file. * a file.
*/ */
idir->dir.d_type = 0; idir->fd_dir.d_type = 0;
if (idir->u.psuedo.next->u.i_ops) if (idir->u.psuedo.fd_next->u.i_ops)
{ {
idir->dir.d_type |= DTYPE_FILE; idir->fd_dir.d_type |= DTYPE_FILE;
} }
/* If the node has child node(s), then we will say that it /* If the node has child node(s), then we will say that it
* is a directory. NOTE: that the node can be both! * is a directory. NOTE: that the node can be both!
*/ */
if (idir->u.psuedo.next->i_child || !idir->u.psuedo.next->u.i_ops) if (idir->u.psuedo.fd_next->i_child || !idir->u.psuedo.fd_next->u.i_ops)
{ {
idir->dir.d_type |= DTYPE_DIRECTORY; idir->fd_dir.d_type |= DTYPE_DIRECTORY;
} }
/* Now get the inode to vist next time that readdir() is called */ /* Now get the inode to vist next time that readdir() is called */
inode_semtake(); inode_semtake();
prev = idir->u.psuedo.next; prev = idir->u.psuedo.fd_next;
idir->u.psuedo.next = prev->i_peer; /* The next node to visit */ idir->u.psuedo.fd_next = prev->i_peer; /* The next node to visit */
if (idir->u.psuedo.next) if (idir->u.psuedo.fd_next)
{ {
/* Increment the reference count on this next node */ /* Increment the reference count on this next node */
idir->u.psuedo.next->i_crefs++; idir->u.psuedo.fd_next->i_crefs++;
} }
inode_semgive(); inode_semgive();
@@ -108,7 +115,7 @@ static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
inode_release(prev); inode_release(prev);
} }
return &idir->dir; return OK;
} }
/************************************************************ /************************************************************
@@ -137,39 +144,72 @@ static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
* *
************************************************************/ ************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct dirent *readdir(DIR *dirp) FAR struct dirent *readdir(DIR *dirp)
{ {
FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp; FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
struct inode *inode;
int ret;
/* Sanity checks */ /* Sanity checks */
if (!idir || !idir->root) if (!idir || !idir->fd_root)
{ {
*get_errno_ptr() = EBADF; ret = EBADF;
return NULL; goto errout;
} }
/* The way we handle the readdir depends on the type of inode /* The way we handle the readdir depends on the type of inode
* that we are dealing with. * that we are dealing with.
*/ */
if (INODE_IS_MOUNTPT(idir->root)) inode = idir->fd_root;
if (INODE_IS_MOUNTPT(inode))
{ {
/* The node is a file system mointpoint */ /* The node is a file system mointpoint. Verify that the mountpoint
* supports the readdir() method
*/
#warning "Mountpoint support not implemented" if (!inode->u.i_mops || !inode->u.i_mops->readdir)
*get_errno_ptr() = ENOSYS; {
return NULL; ret = EACCES;
goto errout;
}
/* Perform the readdir() operation */
ret = inode->u.i_mops->readdir(inode, idir);
} }
else else
{ {
/* The node is part of the root psuedo file system, release /* The node is part of the root psuedo file system, release
* our contained reference to the 'next' inode. * our contained reference to the 'next' inode.
*/ */
return readpsuedodir(idir); ret = readpsuedodir(idir);
} }
/* ret < 0 is an error. Special case: ret = -ENOENT is end of file */
if ( ret < 0)
{
if (ret == -ENOENT)
{
ret = OK;
}
else
{
ret = -ret;
}
goto errout;
}
/* Success */
idir->fd_position++;
return &idir->fd_dir;
errout:
*get_errno_ptr() = ret;
return NULL;
} }
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+4
View File
@@ -43,6 +43,8 @@
#include <nuttx/fs.h> #include <nuttx/fs.h>
#include "fs_internal.h" #include "fs_internal.h"
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/************************************************************ /************************************************************
* Definitions * Definitions
************************************************************/ ************************************************************/
@@ -98,3 +100,5 @@ STATUS register_blockdriver(const char *path,
inode_semgive(); inode_semgive();
return ret; return ret;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
+2
View File
@@ -46,6 +46,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -154,4 +155,5 @@ int rename(const char *oldpath, const char *newpath)
return ERROR; return ERROR;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+25 -8
View File
@@ -48,6 +48,10 @@
* Private Functions * Private Functions
************************************************************/ ************************************************************/
/************************************************************
* Name: rewindpsuedodir
************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
static inline void rewindpsuedodir(struct internal_dir_s *idir) static inline void rewindpsuedodir(struct internal_dir_s *idir)
@@ -58,15 +62,15 @@ static inline void rewindpsuedodir(struct internal_dir_s *idir)
/* Reset the position to the beginning */ /* Reset the position to the beginning */
prev = idir->u.psuedo.next; /* (Save to delete later) */ prev = idir->u.psuedo.fd_next; /* (Save to delete later) */
idir->u.psuedo.next = idir->root; /* The next node to visit */ idir->u.psuedo.fd_next = idir->fd_root; /* The next node to visit */
idir->position = 0; /* Reset position */ idir->fd_position = 0; /* Reset position */
/* Increment the reference count on the root=next node. We /* Increment the reference count on the root=next node. We
* should now have two references on the inode. * should now have two references on the inode.
*/ */
idir->root->i_crefs++; idir->fd_root->i_crefs++;
inode_semgive(); inode_semgive();
/* Then release the reference to the old next inode */ /* Then release the reference to the old next inode */
@@ -100,10 +104,13 @@ static inline void rewindpsuedodir(struct internal_dir_s *idir)
void rewinddir(FAR DIR *dirp) void rewinddir(FAR DIR *dirp)
{ {
struct internal_dir_s *idir = (struct internal_dir_s *)dirp; struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
#ifndef CONFIG_DISABLE_MOUNTPOUNT
struct inode *inode;
#endif
/* Sanity checks */ /* Sanity checks */
if (!idir || !idir->root) if (!idir || !idir->fd_root)
{ {
return; return;
} }
@@ -112,13 +119,23 @@ void rewinddir(FAR DIR *dirp)
* that we are dealing with. * that we are dealing with.
*/ */
if (INODE_IS_MOUNTPT(idir->root)) #ifndef CONFIG_DISABLE_MOUNTPOUNT
inode = idir->fd_root;
if (INODE_IS_MOUNTPT(inode))
{ {
/* The node is a file system mointpoint */ /* The node is a file system mointpoint. Verify that the mountpoint
* supports the rewinddir() method
*/
#warning "Mountpoint support not implemented" if (inode->u.i_mops && inode->u.i_mops->rewinddir)
{
/* Perform the rewinddir() operation */
inode->u.i_mops->rewinddir(inode, idir);
}
} }
else else
#endif
{ {
/* The node is part of the root psuedo file system */ /* The node is part of the root psuedo file system */
+2
View File
@@ -46,6 +46,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -130,4 +131,5 @@ int rmdir(const char *pathname)
return ERROR; return ERROR;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+83 -10
View File
@@ -50,6 +50,10 @@
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
/************************************************************
* Name: seekpsuedodir
************************************************************/
static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset) static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
{ {
struct inode *curr; struct inode *curr;
@@ -62,15 +66,15 @@ static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
* "rewind" to the root dir. * "rewind" to the root dir.
*/ */
if ( offset < idir->position ) if ( offset < idir->fd_position )
{ {
pos = 0; pos = 0;
curr = idir->root; curr = idir->fd_root;
} }
else else
{ {
pos = idir->position; pos = idir->fd_position;
curr = idir->u.psuedo.next; curr = idir->u.psuedo.fd_next;
} }
/* Traverse the peer list starting at the 'root' of the /* Traverse the peer list starting at the 'root' of the
@@ -84,9 +88,9 @@ static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
/* Now get the inode to vist next time that readdir() is called */ /* Now get the inode to vist next time that readdir() is called */
prev = idir->u.psuedo.next; prev = idir->u.psuedo.fd_next;
idir->u.psuedo.next = curr; /* The next node to visit (might be null) */ idir->u.psuedo.fd_next = curr; /* The next node to visit (might be null) */
idir->position = pos; /* Might be beyond the last dirent */ idir->fd_position = pos; /* Might be beyond the last dirent */
if (curr) if (curr)
{ {
@@ -103,6 +107,73 @@ static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
} }
} }
/************************************************************
* Name: seekmountptdir
************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOUNT
static inline void seekmountptdir(struct internal_dir_s *idir, off_t offset)
{
struct inode *inode;
off_t pos;
/* Determine a starting point for the seek. If the seek
* is "forward" from the current position, then we will
* start at the current poisition. Otherwise, we will
* "rewind" to the root dir.
*/
inode = idir->fd_root;
if ( offset < idir->fd_position )
{
if (inode->u.i_mops && inode->u.i_mops->rewinddir)
{
/* Perform the rewinddir() operation */
inode->u.i_mops->rewinddir(inode, idir);
pos = 0;
}
else
{
/* We can't do the seek and there is no way to return
* an error indication.
*/
return;
}
}
else
{
pos = idir->fd_position;
}
/* This is a brute force approach... we will just read
* directory entries until we are at the desired position.
*/
while (pos < offset)
{
if (!inode->u.i_mops || !inode->u.i_mops->readdir ||
inode->u.i_mops->readdir(inode, idir) < 0)
{
/* We can't read the next entry and there is no way to return
* an error indication.
*/
return;
}
/* Increment the position on each successful read */
pos++;
}
/* If we get here the the directory position has been successfully set */
idir->fd_position = pos;
}
#endif
/************************************************************ /************************************************************
* Public Functions * Public Functions
************************************************************/ ************************************************************/
@@ -132,7 +203,7 @@ void seekdir(FAR DIR *dirp, off_t offset)
/* Sanity checks */ /* Sanity checks */
if (!idir || !idir->root) if (!idir || !idir->fd_root)
{ {
return; return;
} }
@@ -141,13 +212,15 @@ void seekdir(FAR DIR *dirp, off_t offset)
* that we are dealing with. * that we are dealing with.
*/ */
if (INODE_IS_MOUNTPT(idir->root)) #ifndef CONFIG_DISABLE_MOUNTPOUNT
if (INODE_IS_MOUNTPT(idir->fd_root))
{ {
/* The node is a file system mointpoint */ /* The node is a file system mointpoint */
#warning "Mountpoint support not implemented" seekmountptdir(idir, offset);
} }
else else
#endif
{ {
/* The node is part of the root psuedo file system */ /* The node is part of the root psuedo file system */
+2 -2
View File
@@ -78,7 +78,7 @@ off_t telldir(FAR DIR *dirp)
{ {
struct internal_dir_s *idir = (struct internal_dir_s *)dirp; struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
if (!idir || !idir->root) if (!idir || !idir->fd_root)
{ {
*get_errno_ptr() = EBADF; *get_errno_ptr() = EBADF;
return (off_t)-1; return (off_t)-1;
@@ -86,7 +86,7 @@ off_t telldir(FAR DIR *dirp)
/* Just return the current position */ /* Just return the current position */
return idir->position; return idir->fd_position;
} }
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+2
View File
@@ -45,6 +45,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -176,4 +177,5 @@ int umount(const char *target)
return ERROR; return ERROR;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+2
View File
@@ -46,6 +46,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -130,4 +131,5 @@ int unlink(const char *pathname)
return ERROR; return ERROR;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */ #endif /* CONFIG_NFILE_DESCRIPTORS */
+2
View File
@@ -44,6 +44,7 @@
#include "fs_internal.h" #include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_DISABLE_MOUNTPOUNT
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
@@ -82,4 +83,5 @@ STATUS unregister_blockdriver(const char *path)
return ret; return ret;
} }
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif #endif
+8
View File
@@ -79,6 +79,7 @@ struct file_operations
/* This structure provides information about the state of a block driver */ /* This structure provides information about the state of a block driver */
#ifndef CONFIG_DISABLE_MOUNTPOUNT
struct geometry struct geometry
{ {
boolean geo_available; /* TRUE: The device is vailable */ boolean geo_available; /* TRUE: The device is vailable */
@@ -114,6 +115,7 @@ struct block_operations
*/ */
struct inode; struct inode;
struct internal_dir_s;
struct mountpt_operations struct mountpt_operations
{ {
/* The mountpoint open method differs from the driver open method /* The mountpoint open method differs from the driver open method
@@ -148,6 +150,9 @@ struct mountpt_operations
/* Directory operations */ /* Directory operations */
int (*opendir)(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir); int (*opendir)(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir);
int (*closedir)(struct inode *mountpt, struct internal_dir_s *dir);
int (*readdir)(struct inode *mountpt, struct internal_dir_s *dir);
int (*rewinddir)(struct inode *mountpt, struct internal_dir_s *dir);
/* General volume-related mountpoint operations: */ /* General volume-related mountpoint operations: */
@@ -163,6 +168,7 @@ struct mountpt_operations
* file stat(), file attributes, file truncation, etc. * file stat(), file attributes, file truncation, etc.
*/ */
}; };
#endif /* CONFIG_DISABLE_MOUNTPOUNT */
/* This structure represents one inode in the Nuttx psuedo-file system */ /* This structure represents one inode in the Nuttx psuedo-file system */
@@ -175,8 +181,10 @@ struct inode
union union
{ {
const struct file_operations *i_ops; /* Driver operations for inode */ const struct file_operations *i_ops; /* Driver operations for inode */
#ifndef CONFIG_DISABLE_MOUNTPOUNT
const struct block_operations *i_bops; /* Block driver operations */ const struct block_operations *i_bops; /* Block driver operations */
const struct mountpt_operations *i_mops; /* Operations on a mountpoint */ const struct mountpt_operations *i_mops; /* Operations on a mountpoint */
#endif
} u; } u;
#ifdef CONFIG_FILE_MODE #ifdef CONFIG_FILE_MODE
mode_t i_mode; /* Access mode flags */ mode_t i_mode; /* Access mode flags */
+1
View File
@@ -48,6 +48,7 @@
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include "os_internal.h" #include "os_internal.h"
#include "clock_internal.h"
#include "pthread_internal.h" #include "pthread_internal.h"
/************************************************************ /************************************************************
+6
View File
@@ -236,6 +236,12 @@ int main(int argc, char **argv, char **envp)
printf("# undef CONFIG_STDIO_BUFFER_SIZE\n"); printf("# undef CONFIG_STDIO_BUFFER_SIZE\n");
printf("# define CONFIG_STDIO_BUFFER_SIZE 0\n"); printf("# define CONFIG_STDIO_BUFFER_SIZE 0\n");
printf("#endif\n\n"); printf("#endif\n\n");
printf("/* If mountpoint support in not included, then no filesystem can\n");
printf(" * be supported.\n");
printf(" */\n\n");
printf("#ifdef CONFIG_DISABLE_MOUNTPOINT\n");
printf("# undef CONFIG_FS_FAT\n");
printf("#endif\n\n");
printf("/* Verbose debug only makes sense if debug is enabled */\n\n"); printf("/* Verbose debug only makes sense if debug is enabled */\n\n");
printf("#ifndef CONFIG_DEBUG\n"); printf("#ifndef CONFIG_DEBUG\n");
printf("# undef CONFIG_DEBUG_VERBOSE\n"); printf("# undef CONFIG_DEBUG_VERBOSE\n");