From f93e30156c033d77182a052549a5e355a5d0a5a0 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 26 May 2007 16:37:37 +0000 Subject: Add readdir() on mountpoints git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@251 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/fs/fs_fat32.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++-- nuttx/fs/fs_opendir.c | 25 +++++++------- nuttx/include/nuttx/fs.h | 4 +++ 3 files changed, 101 insertions(+), 15 deletions(-) diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c index 3f2974109..accfa8007 100644 --- a/nuttx/fs/fs_fat32.c +++ b/nuttx/fs/fs_fat32.c @@ -83,6 +83,9 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence); static int fat_ioctl(FAR struct file *filp, int cmd, unsigned long arg); static int fat_sync(FAR struct file *filp); +static int fat_opendir(struct inode *mountpt, const char *relpath, + struct internal_dir_s *dir); + static int fat_bind(FAR struct inode *blkdriver, const void *data, void **handle); static int fat_unbind(void *handle); @@ -116,6 +119,8 @@ const struct mountpt_operations fat_operations = fat_ioctl, fat_sync, + fat_opendir, + fat_bind, fat_unbind, fat_unlink, @@ -795,7 +800,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer, goto errout_with_semaphore; } } - + /* Copy the partial sector from the user buffer */ writesize = fs->fs_hwsectorsize - sectorindex; @@ -1048,7 +1053,7 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence) } /* If we extended the size of the file, then mark the file as modified. */ - + if ((ff->ff_oflags & O_WROK) != 0 && ff->ff_position > ff->ff_size) { ff->ff_size = ff->ff_position; @@ -1199,6 +1204,84 @@ static int fat_sync(FAR struct file *filp) return ret; } +/**************************************************************************** + * Name: fat_opendir + * + * Description: Open a directory for read access + * + ****************************************************************************/ + +static int fat_opendir(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir) +{ + struct fat_mountpt_s *fs; + struct fat_dirinfo_s dirinfo; + 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; + } + + /* Find the requested directory */ + + ret = fat_finddirentry(fs, &dirinfo, relpath); + if (ret < 0) + { + goto errout_with_semaphore; + } + + /* Check if this is the root directory */ + + if (dirinfo.fd_entry == NULL) + { + /* Handler the FAT12/16 root directory */ + + dir->u.fat.startcluster = 0; + dir->u.fat.currcluster = 0; + dir->u.fat.currsector = fs->fs_rootbase; + dir->u.fat.dirindex = 2; + } + + /* This is not the root directory. Verify that it is some kind of directory */ + + else if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY) + { + /* The entry is not a directory */ + ret = -ENOTDIR; + goto errout_with_semaphore; + } + else + { + /* The entry is a directory */ + + dir->u.fat.startcluster = + ((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) | + DIR_GETFSTCLUSTLO(dirinfo.fd_entry); + dir->u.fat.currcluster = dir->u.fat.startcluster; + dir->u.fat.currsector = fat_cluster2sector(fs, dir->u.fat.currcluster); + dir->u.fat.dirindex = 2; + } + + fat_semgive(fs); + return OK; + +errout_with_semaphore: + fat_semgive(fs); + return ERROR; +} + /**************************************************************************** * Name: fat_bind * diff --git a/nuttx/fs/fs_opendir.c b/nuttx/fs/fs_opendir.c index 24462d53b..0b5a8969f 100644 --- a/nuttx/fs/fs_opendir.c +++ b/nuttx/fs/fs_opendir.c @@ -125,17 +125,6 @@ static inline FAR struct inode *fs_finddirnode(const char *path, const char **re return root; } -/************************************************************ - * Name: fs_openmountptdir - ************************************************************/ - -static inline int fs_openmountptdir(struct inode *inode, const char *relpath, - struct internal_dir_s *dir) -{ -#warning "Mountpoint support not implemented" - return -ENOSYS; -} - /************************************************************ * Public Functions ************************************************************/ @@ -215,9 +204,19 @@ FAR DIR *opendir(const char *path) 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 opendir() method + */ + + if (!inode->u.i_mops || !inode->u.i_mops->opendir) + { + ret = ENOSYS; + goto errout_with_direntry; + } + + /* Perform the opendir() operation */ - ret = fs_openmountptdir(inode, relpath, dir); + ret = inode->u.i_mops->opendir(inode, relpath, dir); if (ret < 0) { ret = -ret; diff --git a/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h index 42ba19661..313624178 100644 --- a/nuttx/include/nuttx/fs.h +++ b/nuttx/include/nuttx/fs.h @@ -145,6 +145,10 @@ struct mountpt_operations int (*sync)(FAR struct file *filp); + /* Directory operations */ + + int (*opendir)(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir); + /* General volume-related mountpoint operations: */ int (*bind)(FAR struct inode *blkdriver, const void *data, void **handle); -- cgit v1.2.3