Fat dir operations seem to work

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@254 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2007-05-26 22:37:57 +00:00
parent 49e73e6d62
commit 955bf72f06
8 changed files with 191 additions and 116 deletions
+55
View File
@@ -46,6 +46,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
/****************************************************************************
@@ -76,10 +77,54 @@ static const char g_testmsg[] = "This is a write test";
static int g_nerrors = 0;
static char g_namebuffer[256];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: fail_read_open
****************************************************************************/
static void show_directories( const char *path, int indent )
{
DIR *dirp;
struct dirent *direntry;
int i;
dirp = opendir(path);
if ( !dirp )
{
printf("show_directories: ERROR opendir(\"%s\") failed with errno=%d\n", path, *get_errno_ptr());
g_nerrors++;
return;
}
for (direntry = readdir(dirp); direntry; direntry = readdir(dirp))
{
for (i = 0; i < 2*indent; i++)
{
putchar(' ');
}
if (DIRENT_ISDIRECTORY(direntry->d_type))
{
char *subdir;
printf("%s/\n", direntry->d_name);
sprintf(g_namebuffer, "%s/%s", path, direntry->d_name);
subdir = strdup(g_namebuffer);
show_directories( subdir, indent + 1);
free(subdir);
}
else
{
printf("%s\n", direntry->d_name);
}
}
closedir(dirp);
}
/****************************************************************************
* Name: fail_read_open
****************************************************************************/
@@ -396,11 +441,13 @@ int user_start(int argc, char *argv[])
{
/* Read a test file that is already on the test file system image */
show_directories("", 0);
read_test_file(g_testfile1);
/* Write a test file into a pre-existing directory on the test file system */
write_test_file(g_testfile2);
show_directories("", 0);
/* Read the file that we just wrote */
@@ -421,6 +468,7 @@ int user_start(int argc, char *argv[])
/* Try unlink() against the test file1. It should succeed. */
succeed_unlink(g_testfile1);
show_directories("", 0);
/* Attempt to open testfile1 should fail with ENOENT */
@@ -437,6 +485,7 @@ int user_start(int argc, char *argv[])
/* Try unlink() against the test file2. It should succeed. */
succeed_unlink(g_testfile2);
show_directories("", 0);
/* Try mkdir() against the test dir1. It should fail with EEXIST. */
@@ -445,10 +494,12 @@ int user_start(int argc, char *argv[])
/* Try rmdir() against the test directory. It should now succeed. */
succeed_rmdir(g_testdir1);
show_directories("", 0);
/* Try mkdir() against the test dir2. It should succeed */
succeed_mkdir(g_testdir2);
show_directories("", 0);
/* Try mkdir() against the test dir2. It should fail with EXIST */
@@ -457,6 +508,7 @@ int user_start(int argc, char *argv[])
/* Write a test file into a new directory on the test file system */
write_test_file(g_testfile3);
show_directories("", 0);
/* Read the file that we just wrote */
@@ -465,6 +517,7 @@ int user_start(int argc, char *argv[])
/* Use mkdir() to create test dir3. It should succeed */
succeed_mkdir(g_testdir3);
show_directories("", 0);
/* Try rename() on the root directory. Should fail with EXDEV*/
@@ -477,10 +530,12 @@ int user_start(int argc, char *argv[])
/* Try rename() to a non-existing directory. Should succeed */
succeed_rename(g_testdir3, g_testdir4);
show_directories("", 0);
/* Try rename() of file. Should work. */
succeed_rename(g_testfile3, g_testfile4);
show_directories("", 0);
/* Make sure that we can still read the renamed file */
+9 -9
View File
@@ -254,15 +254,6 @@ static void cmd_ls(const char *cmd, char *arg)
break;
}
if (DIRENT_ISFILE(entryp->d_type))
{
#ifdef CONFIG_FULL_PATH
printf(" %s/%s\n", arg, entryp->d_name);
#else
printf(" %s\n", entryp->d_name);
#endif
}
if (DIRENT_ISDIRECTORY(entryp->d_type))
{
#ifdef CONFIG_FULL_PATH
@@ -271,6 +262,15 @@ static void cmd_ls(const char *cmd, char *arg)
printf(" %s/\n", entryp->d_name);
#endif
}
else
{
#ifdef CONFIG_FULL_PATH
printf(" %s/%s\n", arg, entryp->d_name);
#else
printf(" %s\n", entryp->d_name);
#endif
}
}
closedir(dirp);
}
+1 -1
View File
@@ -1262,7 +1262,7 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct intern
/* This is not the root directory. Verify that it is some kind of directory */
else if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY)
else if ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY) == 0)
{
/* The entry is not a directory */
ret = -ENOTDIR;
+21 -1
View File
@@ -69,6 +69,13 @@
#define INODE_SET_MOUNTPT(i) \
((i)->i_flags = (((i)->i_flags & ~FSNODEFLAG_TYPE_MASK) | FSNODEFLAG_TYPE_MOUNTPT))
/* Mountpoint fd_flags values */
#define DIRENTFLAGS_PSUEDONODE 1
#define DIRENT_SETPSUEDONODE(f) do (f) |= DIRENTFLAGS_PSUEDONODE; while (0)
#define DIRENT_ISPSUEDONODE(f) (((f) & DIRENTFLAGS_PSUEDONODE) != 0)
/****************************************************************************
* Public Types
****************************************************************************/
@@ -87,7 +94,7 @@ struct fs_psuedodir_s
struct inode *fd_next; /* The inode for the next call to readdir() */
};
#ifdef CONFIG_FS_FAT
#if defined(CONFIG_FS_FAT) && !defined(CONFIG_DISABLE_MOUNTPOINT)
/* For fat, we need to retun the start cluster, current cluster, current
* sector and current directory index.
*/
@@ -113,6 +120,12 @@ struct internal_dir_s
struct inode *fd_root;
/* At present, only mountpoints require special handling flags */
#ifndef CONFIG_DISABLE_MOUNTPOINT
unsigned int fd_flags;
#endif
/* This keeps track of the current directory position for telldir */
off_t fd_position;
@@ -125,9 +138,16 @@ struct internal_dir_s
union
{
/* Private data used by the built-in psuedo-file system */
struct fs_psuedodir_s psuedo;
/* Private data used by other file systems */
#ifndef CONFIG_DISABLE_MOUNTPOINT
#ifdef CONFIG_FS_FAT
struct fs_fatdir_s fat;
#endif
#endif
} u;
+78 -96
View File
@@ -50,81 +50,6 @@
* Private Functions
************************************************************/
/************************************************************
* Name: fs_finddirnode
*
* Description:
* This is called from the opendir() logic to get a reference
* to the inode associated with a directory. There are no
* real directories in this design; For our purposes, a
* directory inode is simply one that has children or one
* that is a mountpoint for a "real" file system
*
************************************************************/
static inline FAR struct inode *fs_finddirnode(const char *path, const char **relpath)
{
FAR struct inode *node;
FAR struct inode *root = NULL;
/* If we are given 'nothing' then we will interpret this as
* request for the root inode.
*/
if (!path || *path == 0 || strcmp(path, "/") == 0)
{
return root_inode;
}
/* We don't know what to do with relative pathes */
if (*path != '/')
{
return NULL;
}
/* Find the node matching the path. */
inode_semtake();
node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, relpath);
if (node)
{
/* Is this a not in the psuedo filesystem? */
if (INODE_IS_MOUNTPT(node))
{
/* Yes, then return the inode itself as the 'root' of
* the directory. The actually directory is at relpath into the
* mounted filesystem. Increment the count of references
* on the inode.
*/
root = node;
root->i_crefs++;
}
else
{
/* It is a node in the psuedo filesystem. Does the inode have a child?
* If so that the child would be the 'root' of a list of nodes under
* the directory.
*/
root = node->i_child;
if (root)
{
/* If found, then increment the count of
* references on the child node.
*/
root->i_crefs++;
}
}
}
inode_semgive();
return root;
}
/************************************************************
* Public Functions
************************************************************/
@@ -161,22 +86,45 @@ static inline FAR struct inode *fs_finddirnode(const char *path, const char **re
FAR DIR *opendir(const char *path)
{
FAR struct inode *inode;
FAR struct inode *inode = NULL;
FAR struct internal_dir_s *dir;
const char *relpath;
boolean isroot = FALSE;
int ret;
/* Get an inode corresponding to the path. On successful
* return, we will hold on reference count on the inode.
/* If we are given 'nothing' then we will interpret this as
* request for the root inode.
*/
inode = fs_finddirnode(path, &relpath);
if (!path || *path == 0 || strcmp(path, "/") == 0)
{
inode_semgive();
inode = root_inode;
isroot = TRUE;
}
else
{
/* We don't know what to do with relative pathes */
if (*path != '/')
{
return NULL;
}
/* Find the node matching the path. */
inode_semtake();
inode = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, &relpath);
}
/* Did we get an inode? */
if (!inode)
{
/* 'path' is not a directory.*/
/* 'path' is not a does not exist.*/
ret = ENOTDIR;
goto errout;
goto errout_with_semaphore;
}
/* Allocate a type DIR -- which is little more than an inode
@@ -189,7 +137,7 @@ FAR DIR *opendir(const char *path)
/* Insufficient memory to complete the operation.*/
ret = ENOMEM;
goto errout_with_inode;
goto errout_with_semaphore;
}
/* Populate the DIR structure and return it to the caller. The way that
@@ -200,20 +148,29 @@ FAR DIR *opendir(const char *path)
dir->fd_root = inode; /* Save the inode where we start */
dir->fd_position = 0; /* This is the position in the read stream */
/* Is this a not in the psuedo filesystem? */
/* Is this a node in the psuedo filesystem? Or a mountpoint? */
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode))
{
/* Yes, then return the inode itself as the 'root' of
* the directory. The actually directory is at relpath into the
* mounted filesystem.
*/
#ifndef CONFIG_DISABLE_MOUNTPOUNT
if (INODE_IS_MOUNTPT(inode))
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the opendir() method
*/
* supports the opendir() method
*/
if (!inode->u.i_mops || !inode->u.i_mops->opendir)
{
{
ret = ENOSYS;
goto errout_with_direntry;
}
}
/* Take reference to the mountpoint inode (fd_root) */
inode_addref(inode);
/* Perform the opendir() operation */
@@ -221,27 +178,52 @@ FAR DIR *opendir(const char *path)
if (ret < 0)
{
ret = -ret;
goto errout_with_direntry;
goto errout_with_inode;
}
}
else
#endif
{
/* The node is part of the root psuedo file system */
/* The node is part of the root psuedo file system. Does the inode have a child?
* If so that the child would be the 'root' of a list of nodes under
* the directory.
*/
inode_addref(inode); /* Now we have two references on inode */
if (!isroot)
{
inode = inode->i_child;
if (!inode)
{
ret = ENOTDIR;
goto errout_with_direntry;
}
}
/* It looks we have a valid psuedo-filesystem node. Take two references
* on the inode -- one for the parent (fd_root) and one for the child (fd_next).
*/
inode_addref(inode);
inode_addref(inode);
dir->u.psuedo.fd_next = inode; /* This is the next node to use for readdir() */
/* Flag the inode as belonging to the psuedo-filesystem */
#ifndef CONFIG_DISABLE_MOUNTPOINT
DIRENT_SETPSUEDONODE(dir->fd_flags);
#endif
}
inode_semgive();
return ((DIR*)dir);
/* Nasty goto's make error handling simpler */
errout_with_direntry:
free(dir);
errout_with_inode:
inode_release(inode);
errout:
errout_with_direntry:
free(dir);
errout_with_semaphore:
inode_semgive();
*get_errno_ptr() = ret;
return NULL;
}
+22 -6
View File
@@ -82,7 +82,20 @@ static inline int readpsuedodir(struct internal_dir_s *idir)
idir->fd_dir.d_type = 0;
if (idir->u.psuedo.fd_next->u.i_ops)
{
idir->fd_dir.d_type |= DTYPE_FILE;
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_BLOCK(idir->u.psuedo.fd_next))
{
idir->fd_dir.d_type |= DTYPE_BLK;
}
if (INODE_IS_MOUNTPT(idir->u.psuedo.fd_next))
{
idir->fd_dir.d_type |= DTYPE_DIRECTORY;
}
else
#endif
{
idir->fd_dir.d_type |= DTYPE_CHR;
}
}
/* If the node has child node(s), then we will say that it
@@ -147,7 +160,9 @@ static inline int readpsuedodir(struct internal_dir_s *idir)
FAR struct dirent *readdir(DIR *dirp)
{
FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct inode *inode;
#endif
int ret;
/* Sanity checks */
@@ -162,8 +177,9 @@ FAR struct dirent *readdir(DIR *dirp)
* that we are dealing with.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
inode = idir->fd_root;
if (INODE_IS_MOUNTPT(inode))
if (INODE_IS_MOUNTPT(inode) && !DIRENT_ISPSUEDONODE(idir->fd_flags))
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the readdir() method
@@ -172,7 +188,7 @@ FAR struct dirent *readdir(DIR *dirp)
if (!inode->u.i_mops || !inode->u.i_mops->readdir)
{
ret = EACCES;
goto errout;
goto errout;
}
/* Perform the readdir() operation */
@@ -180,10 +196,10 @@ FAR struct dirent *readdir(DIR *dirp)
ret = inode->u.i_mops->readdir(inode, idir);
}
else
#endif
{
/* The node is part of the root psuedo file system, release
* our contained reference to the 'next' inode.
*/
/* The node is part of the root psuedo file system */
ret = readpsuedodir(idir);
}
+5 -1
View File
@@ -54,9 +54,13 @@
*/
#define DTYPE_FILE 0x01
#define DTYPE_DIRECTORY 0x02
#define DTYPE_CHR 0x02
#define DTYPE_BLK 0x04
#define DTYPE_DIRECTORY 0x08
#define DIRENT_ISFILE(dtype) (((dtype) & DTYPE_FILE) != 0 )
#define DIRENT_ISCHR(dtype) (((dtype) & DTYPE_CHR) != 0 )
#define DIRENT_ISBLK(dtype) (((dtype) & DTYPE_BLK) != 0 )
#define DIRENT_ISDIRECTORY(dtype) (((dtype) & DTYPE_DIRECTORY) != 0 )
/************************************************************
-2
View File
@@ -209,8 +209,6 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value)
void pthread_destroyjoin(FAR join_t *pjoin)
{
int status;
dbg("pjoin=0x%p\n", pjoin);
/* Remove the join info from the set of joins */