From a75eeec47f39797429d5cae90db057374aeeac5d Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 14 May 2007 11:12:09 +0000 Subject: umount and fat fixes git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@227 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/examples/mount/mount_main.c | 13 ++++- nuttx/fs/fs_fat32.c | 100 ++++++++++++++++++++++++++++++++------ nuttx/fs/fs_fat32.h | 1 + nuttx/fs/fs_inoderemove.c | 4 +- nuttx/fs/fs_open.c | 2 +- nuttx/fs/fs_umount.c | 15 +++--- nuttx/include/nuttx/fs.h | 8 +-- 7 files changed, 116 insertions(+), 27 deletions(-) diff --git a/nuttx/examples/mount/mount_main.c b/nuttx/examples/mount/mount_main.c index 541530d6b..3ba8f96d5 100644 --- a/nuttx/examples/mount/mount_main.c +++ b/nuttx/examples/mount/mount_main.c @@ -108,10 +108,21 @@ int user_start(int argc, char *argv[]) } else { + char buffer[128]; + int nbytes = read(fd, buffer, 128); + if (nbytes < 0) + { + printf("main: failed to read from %s, errno=%d\n", g_testfile1, *get_errno_ptr()); + } + else + { + buffer[127]='\0'; + printf("main: Read \"%s\" from %s\n", buffer, g_testfile1); + } close(fd); } - printf("main: opening %s for reading\n", g_testfile2); + printf("main: opening %s for writing\n", g_testfile2); fd = open(g_testfile2, O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd < 0) diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c index 00515efe7..6f3e35e74 100644 --- a/nuttx/fs/fs_fat32.c +++ b/nuttx/fs/fs_fat32.c @@ -221,8 +221,8 @@ * Private Function Prototypes ****************************************************************************/ -static int fat_open(FAR struct file *filp, const char *rel_path, - int oflags, mode_t mode); +static int fat_open(FAR struct file *filp, FAR struct inode *inode, + const char *rel_path, 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); static ssize_t fat_write(FAR struct file *filp, const char *buffer, @@ -770,20 +770,62 @@ static int fat_mount(struct fat_mountpt_s *fs, boolean writeable) * Name: fat_open ****************************************************************************/ -static int fat_open(FAR struct file *filp, const char *rel_path, - int oflags, mode_t mode) +static int fat_open(FAR struct file *filp, FAR struct inode *inode, + const char *rel_path, int oflags, mode_t mode) { - struct fat_mountpt_s *fs = filp->f_priv; - int ret; + struct fat_mountpt_s *fs = (struct fat_mountpt_s *)inode->i_private; + struct fat_file_s *ff; + int ret = OK; /* Make sure that the mount is still healthy */ + if (!fs) + { + ret = -ENOSYS; + goto errout; + } - ret = fat_checkmount(fs); + fat_semtake(fs); + ret = fat_checkmount(fs); if (ret != OK) { - return ret; + goto errout_with_semaphore; } - return -ENOSYS; + + /* Allocate a new private instance for the struct file */ + + ff = (struct fat_file_s *)malloc(sizeof(struct fat_file_s)); + if (!ff) + { + ret = -ENOMEM; + goto errout_with_semaphore; + } + + /* Find the requested path and open or create the file */ +#warning "Open logic missing" + + /* Initialize the new private instance */ + + ff->ff_parent = fs; + ff->ff_open = TRUE; + + /* Then insert the new instance into the mountpoint structure. + * It needs to be there (1) to handle error conditions that effect + * all files, and (2) to inform the umount logic that we are busy + * (but a simple reference count could have done that). + */ + + ff->ff_next = fs->fs_head; + fs->fs_head = ff->ff_next; + + fat_semgive(fs); + return OK; + + errout_with_alloc: + free(ff); + errout_with_semaphore: + fat_semgive(fs); + errout: + return ret; } /**************************************************************************** @@ -792,7 +834,13 @@ static int fat_open(FAR struct file *filp, const char *rel_path, static int fat_close(FAR struct file *filp) { - struct fat_mountpt_s *fs = filp->f_priv; + struct fat_file_s *ff = filp->f_priv; + struct fat_mountpt_s *fs; + + if (!ff || !(fs = ff->ff_parent)) + { + return -EINVAL; + } /* Do not check if the mount is healthy. We must support closing of * the file even when there is healthy mount. @@ -807,9 +855,15 @@ static int fat_close(FAR struct file *filp) static ssize_t fat_read(FAR struct file *filp, char *buffer, size_t buflen) { - struct fat_mountpt_s *fs = filp->f_priv; + struct fat_file_s *ff = filp->f_priv; + struct fat_mountpt_s *fs; int ret; + if (!ff || !(fs = ff->ff_parent)) + { + return -EINVAL; + } + /* Make sure that the mount is still healthy */ ret = fat_checkmount(fs); @@ -827,9 +881,15 @@ static ssize_t fat_read(FAR struct file *filp, char *buffer, size_t buflen) static ssize_t fat_write(FAR struct file *filp, const char *buffer, size_t buflen) { - struct fat_mountpt_s *fs = filp->f_priv; + struct fat_file_s *ff = filp->f_priv; + struct fat_mountpt_s *fs; int ret; + if (!ff || !(fs = ff->ff_parent)) + { + return -EINVAL; + } + /* Make sure that the mount is still healthy */ ret = fat_checkmount(fs); @@ -846,9 +906,15 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer, static off_t fat_seek(FAR struct file *filp, off_t offset, int whence) { - struct fat_mountpt_s *fs = filp->f_priv; + struct fat_file_s *ff = filp->f_priv; + struct fat_mountpt_s *fs; int ret; + if (!ff || !(fs = ff->ff_parent)) + { + return -EINVAL; + } + /* Make sure that the mount is still healthy */ ret = fat_checkmount(fs); @@ -865,9 +931,15 @@ 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) { - struct fat_mountpt_s *fs = filp->f_priv; + struct fat_file_s *ff = filp->f_priv; + struct fat_mountpt_s *fs; int ret; + if (!ff || !(fs = ff->ff_parent)) + { + return -EINVAL; + } + /* Make sure that the mount is still healthy */ ret = fat_checkmount(fs); diff --git a/nuttx/fs/fs_fat32.h b/nuttx/fs/fs_fat32.h index 3368029ba..59588616a 100644 --- a/nuttx/fs/fs_fat32.h +++ b/nuttx/fs/fs_fat32.h @@ -196,6 +196,7 @@ struct fat_mountpt_s struct fat_file_s { struct fat_file_s *ff_next; /* File structures are retained in a singly linked list */ + struct fat_mountpt_s *ff_parent; boolean ff_open; /* TRUE: The file is (still) open */ }; diff --git a/nuttx/fs/fs_inoderemove.c b/nuttx/fs/fs_inoderemove.c index cb80dcbc5..b6b56c4af 100644 --- a/nuttx/fs/fs_inoderemove.c +++ b/nuttx/fs/fs_inoderemove.c @@ -112,9 +112,9 @@ STATUS inode_remove(const char *path) FAR struct inode *left; FAR struct inode *parent; - if (*path && path[0] == '/') + if (!*path || path[0] != '/') { - return ERROR; + return -EINVAL; } /* Find the node to delete */ diff --git a/nuttx/fs/fs_open.c b/nuttx/fs/fs_open.c index e954fb743..b0c9fee43 100644 --- a/nuttx/fs/fs_open.c +++ b/nuttx/fs/fs_open.c @@ -154,7 +154,7 @@ int open(const char *path, int oflags, ...) if (INODE_IS_MOUNTPT(inode)) { status = inode->u.i_mops->open((FAR struct file*)&list->fl_files[fd], - relpath, oflags, mode); + inode, relpath, oflags, mode); } else { diff --git a/nuttx/fs/fs_umount.c b/nuttx/fs/fs_umount.c index b18407f20..c4abde95b 100644 --- a/nuttx/fs/fs_umount.c +++ b/nuttx/fs/fs_umount.c @@ -104,12 +104,11 @@ int umount(const char *target) /* Find the mountpt */ - inode_semtake(); mountpt_inode = inode_find(target, NULL); if (!mountpt_inode) { errcode = ENOENT; - goto errout_with_semaphore; + goto errout; } /* Verify that the inode is a mountpoint */ @@ -137,18 +136,19 @@ int umount(const char *target) * performed, or a negated error code on a failure. */ + inode_semtake(); /* Hold the semaphore through the unbind logic */ status = mountpt_inode->u.i_mops->unbind( mountpt_inode->i_private ); if (status < 0) { /* The inode is unhappy with the blkdrvr for some reason */ errcode = -status; - goto errout_with_mountpt; + goto errout_with_semaphore; } else if (status > 0) { errcode = EBUSY; - goto errout_with_mountpt; + goto errout_with_semaphore; } /* Successfully unbound */ @@ -157,17 +157,20 @@ int umount(const char *target) /* Remove the inode */ + inode_semgive(); /* Need to release for inode_release */ inode_release(mountpt_inode); + + inode_semtake(); /* Need to hold for inode_remove */ status = inode_remove(target); inode_semgive(); return status; /* A lot of goto's! But they make the error handling much simpler */ - errout_with_mountpt: - inode_release(mountpt_inode); errout_with_semaphore: inode_semgive(); + errout_with_mountpt: + inode_release(mountpt_inode); errout: *get_errno_ptr() = errcode; return ERROR; diff --git a/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h index f813a44a2..06eefc8f7 100644 --- a/nuttx/include/nuttx/fs.h +++ b/nuttx/include/nuttx/fs.h @@ -117,11 +117,13 @@ struct inode; struct mountpt_operations { /* The mountpoint open method differs from the driver open method - * because it receives the relative path into the mountpoint. + * because it receives (1) the inode that contains the mountpoint + * private data, (2) the relative path into the mountpoint, and (3) + * information to manage privileges. */ - int (*open)(FAR struct file *filp, const char *rel_path, - int oflags, mode_t mode); + int (*open)(FAR struct file *filp, FAR struct inode *inode, + const char *rel_path, int oflags, mode_t mode); /* The following methods must be identical in signature and position because * the struct file_operations and struct mountp_operations are treated like -- cgit v1.2.3