From 039a51bde4bc3f21fe68c3f4cff966fde2532faa Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 9 May 2007 00:04:03 +0000 Subject: Add support for block drivers git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@206 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/fs/Makefile | 5 +- nuttx/fs/fs_inode.c | 20 ++-- nuttx/fs/fs_inodefind.c | 4 +- nuttx/fs/fs_inodefinddir.c | 2 +- nuttx/fs/fs_inoderemove.c | 155 +++++++++++++++++++++++++++ nuttx/fs/fs_inodereserve.c | 206 +++++++++++++++++++++++++++++++++++ nuttx/fs/fs_internal.h | 72 +++++++++---- nuttx/fs/fs_ioctl.c | 4 +- nuttx/fs/fs_open.c | 34 ++++-- nuttx/fs/fs_read.c | 4 +- nuttx/fs/fs_readdir.c | 4 +- nuttx/fs/fs_registerblockdriver.c | 100 +++++++++++++++++ nuttx/fs/fs_registerdriver.c | 101 +++++++++++++++++ nuttx/fs/fs_registerinode.c | 220 -------------------------------------- nuttx/fs/fs_unregisterinode.c | 155 --------------------------- nuttx/fs/fs_write.c | 4 +- 16 files changed, 665 insertions(+), 425 deletions(-) create mode 100644 nuttx/fs/fs_inoderemove.c create mode 100644 nuttx/fs/fs_inodereserve.c create mode 100644 nuttx/fs/fs_registerblockdriver.c create mode 100644 nuttx/fs/fs_registerdriver.c delete mode 100644 nuttx/fs/fs_registerinode.c delete mode 100644 nuttx/fs/fs_unregisterinode.c diff --git a/nuttx/fs/Makefile b/nuttx/fs/Makefile index 8c57d6129..9a0638579 100644 --- a/nuttx/fs/Makefile +++ b/nuttx/fs/Makefile @@ -43,8 +43,9 @@ AOBJS = $(ASRCS:.S=$(OBJEXT)) CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \ fs_opendir.c fs_closedir.c fs_readdir.c fs_readdirr.c \ fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_files.c \ - fs_inode.c fs_inodefind.c fs_inodefinddir.c fs_registerinode.c \ - fs_unregisterinode.c fs_inodeaddref.c fs_inoderelease.c + fs_inode.c fs_inodefind.c fs_inodefinddir.c fs_inodereserve.c \ + fs_inoderemove.c fs_registerdriver.c fs_registerblockdriver.c \ + fs_inodeaddref.c fs_inoderelease.c COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) diff --git a/nuttx/fs/fs_inode.c b/nuttx/fs/fs_inode.c index 9c7cf3d07..274dcf1a4 100644 --- a/nuttx/fs/fs_inode.c +++ b/nuttx/fs/fs_inode.c @@ -209,7 +209,8 @@ void inode_semgive(void) FAR struct inode *inode_search(const char **path, FAR struct inode **peer, - FAR struct inode **parent) + FAR struct inode **parent, + const char **relpath) { const char *name = *path + 1; /* Skip over leading '/' */ FAR struct inode *node = root_inode; @@ -247,18 +248,25 @@ FAR struct inode *inode_search(const char **path, else { - /* Now there are two more possibilities: + /* Now there are three more possibilities: * (1) This is the node that we are looking for or, - * (2) the node we are looking for is "blow" this one. + * (2) The node we are looking for is "below" this one. + * (3) This node is a mountpoint and will absorb all request + * below this one */ name = inode_nextname(name); - if (!*name) + if (!*name || INODE_IS_MOUNTPT(node)) { - /* We are at the end of the path, so this must be - * the node we are looking for. + /* Either (1) we are at the end of the path, so this must be the + * node we are looking for or else (2) this node is a mountpoint + * and will handle the remaining part of the pathname */ + if (relpath) + { + *relpath = name; + } break; } else diff --git a/nuttx/fs/fs_inodefind.c b/nuttx/fs/fs_inodefind.c index 0df0b2ad5..215710311 100644 --- a/nuttx/fs/fs_inodefind.c +++ b/nuttx/fs/fs_inodefind.c @@ -74,7 +74,7 @@ * ************************************************************/ -FAR struct inode *inode_find(const char *path) +FAR struct inode *inode_find(const char *path, const char **relpath) { FAR struct inode *node; @@ -88,7 +88,7 @@ FAR struct inode *inode_find(const char *path) */ inode_semtake(); - node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL); + node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, relpath); if (node) { node->i_crefs++; diff --git a/nuttx/fs/fs_inodefinddir.c b/nuttx/fs/fs_inodefinddir.c index 73d818ba8..e9043903e 100644 --- a/nuttx/fs/fs_inodefinddir.c +++ b/nuttx/fs/fs_inodefinddir.c @@ -104,7 +104,7 @@ FAR struct inode *inode_finddir(const char *path) /* Handle some special cases */ - node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL); + node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, (FAR const char*)NULL); if (node) { /* Does the inode have a child? If so that the child diff --git a/nuttx/fs/fs_inoderemove.c b/nuttx/fs/fs_inoderemove.c new file mode 100644 index 000000000..58ac734e7 --- /dev/null +++ b/nuttx/fs/fs_inoderemove.c @@ -0,0 +1,155 @@ +/**************************************************************************** + * fs_inoderemove.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "fs_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: inode_unlink + ****************************************************************************/ + +static void inode_unlink(struct inode *node, + struct inode *peer, + struct inode *parent) +{ + /* If peer is non-null, then remove the node from the right of + * of that peer node. + */ + + if (peer) + { + peer->i_peer = node->i_peer; + } + + /* If parent is non-null, then remove the node from head of + * of the list of children. + */ + + else if (parent) + { + parent->i_child = node->i_peer; + } + + /* Otherwise, we must be removing the root inode. */ + + else + { + root_inode = node->i_peer; + } + node->i_peer = NULL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: inode_remove + ****************************************************************************/ + +STATUS inode_remove(const char *path) +{ + const char *name = path; + FAR struct inode *node; + FAR struct inode *left; + FAR struct inode *parent; + + if (*path && path[0] == '/') + { + return ERROR; + } + + /* Find the node to delete */ + + inode_semtake(); + node = inode_search(&name, &left, &parent, NULL); + if (node) + { + /* Found it, now remove it from the tree */ + + inode_unlink(node, left, parent); + + /* We cannot delete it if there reference to the inode */ + + if (node->i_crefs) + { + /* In that case, we will mark it deleted, when the FS + * releases the inode, we will then, finally delete + * the subtree. + */ + + node->i_flags |= FSNODEFLAG_DELETED; + inode_semgive(); + } + else + { + /* And delete it now -- recursively to delete all of its children */ + + inode_semgive(); + inode_free(node->i_child); + free(node); + return OK; + } + } + + /* The node does not exist or it has references */ + + inode_semgive(); + return ERROR; +} diff --git a/nuttx/fs/fs_inodereserve.c b/nuttx/fs/fs_inodereserve.c new file mode 100644 index 000000000..ad010e21e --- /dev/null +++ b/nuttx/fs/fs_inodereserve.c @@ -0,0 +1,206 @@ +/************************************************************ + * fs_registerreserve.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include +#include +#include +#include +#include +#include "fs_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Public Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Name: inode_namelen + ************************************************************/ + +static int inode_namelen(const char *name) +{ + const char *tmp = name; + while(*tmp && *tmp != '/') tmp++; + return tmp - name; +} + +/************************************************************ + * Name: inode_namecpy + ************************************************************/ + +static void inode_namecpy(char *dest, const char *src) +{ + while(*src && *src != '/') *dest++ = *src++; + *dest='\0'; +} + +/************************************************************ + * Name: inode_alloc + ************************************************************/ + +static FAR struct inode *inode_alloc(const char *name) +{ + int namelen = inode_namelen(name); + FAR struct inode *node = (FAR struct inode*)zalloc(FSNODE_SIZE(namelen)); + if (node) + { + inode_namecpy(node->i_name, name); + } + return node; +} + +/************************************************************ + * Name: inode_insert + ************************************************************/ + +static void inode_insert(FAR struct inode *node, + FAR struct inode *peer, + FAR struct inode *parent) +{ + /* If peer is non-null, then new node simply goes to the right + * of that peer node. + */ + + if (peer) + { + node->i_peer = peer->i_peer; + peer->i_peer = node; + } + + /* If parent is non-null, then it must go at the head of its + * list of children. + */ + + else if (parent) + { + node->i_peer = parent->i_child; + parent->i_child = node; + } + + /* Otherwise, this must be the new root_inode */ + + else + { + node->i_peer = root_inode; + root_inode = node; + } +} + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: inode_reserve + ************************************************************/ + +FAR struct inode *inode_reserve(const char *path) +{ + const char *name = path; + FAR struct inode *left; + FAR struct inode *parent; + + if (!*path || path[0] != '/') + { + return NULL; + } + + /* Find the location to insert the new subtree */ + + if (inode_search(&name, &left, &parent, NULL) != NULL) + { + /* Is is an error if the node already exists in the tree */ + + return NULL; + } + + /* Now we now where to insert the subtree */ + + for (;;) + { + FAR struct inode *node; + + /* Create a new node -- we need to know if this is the + * the leaf node or some intermediary. We can find this + * by looking at the next name. + */ + + const char *next_name = inode_nextname(name); + if (*next_name) + { + /* Insert an operationless node */ + + node = inode_alloc(name); + if (node) + { + inode_insert(node, left, parent); + + /* Set up for the next time through the loop */ + + name = next_name; + left = NULL; + parent = node; + continue; + } + } + else + { + node = inode_alloc(name); + if (node) + { + inode_insert(node, left, parent); + return node; + } + } + + /* We get here on failures to allocate node memory */ + return NULL; + } +} diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h index 111f56aae..e63d6029f 100644 --- a/nuttx/fs/fs_internal.h +++ b/nuttx/fs/fs_internal.h @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * fs_internal.h * * Copyright (C) 2007 Gregory Nutt. All rights reserved. @@ -31,29 +31,47 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ #ifndef __FS_INTERNAL_H #define __FS_INTERNAL_H -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include #include #include #include -/************************************************************ +/**************************************************************************** * Definitions - ************************************************************/ - -#define FSNODEFLAG_DELETED 0x00000001 - -/************************************************************ + ****************************************************************************/ + +#define FSNODEFLAG_TYPE_MASK 0x00000003 +#define FSNODEFLAG_TYPE_DRIVER 0x00000000 +#define FSNODEFLAG_TYPE_BLOCK 0x00000001 +#define FSNODEFLAG_TYPE_MOUNTPT 0x00000002 +#define FSNODEFLAG_DELETED 0x00000004 + +#define INODE_IS_DRIVER(i) \ + (((i)->i_flags & FSNODEFLAG_TYPE_MASK) == FSNODEFLAG_TYPE_DRIVER) +#define INODE_IS_BLOCK(i) \ + (((i)->i_flags & FSNODEFLAG_TYPE_BLOCK) == FSNODEFLAG_TYPE_BLOCK) +#define INODE_IS_MOUNTPT(i) \ + (((i)->i_flags & FSNODEFLAG_TYPE_MOUNTPT) == FSNODEFLAG_TYPE_MOUNTPT) + +#define INODE_SET_DRIVER(i) \ + ((i)->i_flags &= ~FSNODEFLAG_TYPE_MASK) +#define INODE_SET_BLOCK(i) \ + ((i)->i_flags = (((i)->i_flags & ~FSNODEFLAG_TYPE_MASK) | FSNODEFLAG_TYPE_BLOCK)) +#define INODE_SET_MOUNTP(i) \ + ((i)->i_flags = (((i)->i_flags & ~FSNODEFLAG_TYPE_MASK) | FSNODEFLAG_TYPE_MOUNTP)) + +/**************************************************************************** * Public Types - ************************************************************/ + ****************************************************************************/ /* The internal representation of type DIR is just a * container for an inode reference and a dirent structure. @@ -69,15 +87,15 @@ struct internal_dir_s * is called */ }; -/************************************************************ +/**************************************************************************** * Global Variables - ************************************************************/ + ****************************************************************************/ extern FAR struct inode *root_inode; -/************************************************************ +/**************************************************************************** * Pulblic Function Prototypes - ************************************************************/ + ****************************************************************************/ #undef EXTERN #if defined(__cplusplus) @@ -87,34 +105,42 @@ extern "C" { #define EXTERN extern #endif -/* fs_inode.c ***********************************************/ +/* fs_inode.c ***************************************************************/ EXTERN void inode_semtake(void); EXTERN void inode_semgive(void); EXTERN FAR struct inode *inode_search(const char **path, FAR struct inode **peer, - FAR struct inode **parent); + FAR struct inode **parent, + const char **relpath); EXTERN void inode_free(FAR struct inode *node); EXTERN const char *inode_nextname(const char *name); +/* fs_inodereserver.c ********************************************************/ + +EXTERN FAR struct inode *inode_reserve(const char *path); + +/* fs_inoderemove.c **********************************************************/ + +EXTERN STATUS inode_remove(const char *path); -/* fs_inodefind.c ********************************************/ +/* fs_inodefind.c ************************************************************/ -EXTERN FAR struct inode *inode_find(const char *path); +EXTERN FAR struct inode *inode_find(const char *path, const char **relpath); -/* fs_inodefinddir.c *****************************************/ +/* fs_inodefinddir.c *********************************************************/ EXTERN FAR struct inode *inode_finddir(const char *path); -/* fs_inodeaddref.c ******************************************/ +/* fs_inodeaddref.c **********************************************************/ EXTERN void inode_addref(FAR struct inode *inode); -/* fs_inoderelease.c *****************************************/ +/* fs_inoderelease.c *********************************************************/ EXTERN void inode_release(FAR struct inode *inode); -/* fs_files.c ***********************************************/ +/* fs_files.c ***************************************************************/ #if CONFIG_NFILE_DESCRIPTORS >0 EXTERN void weak_function files_initialize(void); diff --git a/nuttx/fs/fs_ioctl.c b/nuttx/fs/fs_ioctl.c index 2a49aec9b..8035c4cc4 100644 --- a/nuttx/fs/fs_ioctl.c +++ b/nuttx/fs/fs_ioctl.c @@ -77,11 +77,11 @@ int ioctl(int fd, int req, unsigned long arg) /* Is a driver registered? Does it support the ioctl method? */ - if (inode && inode->i_ops && inode->i_ops->ioctl) + if (inode && inode->u.i_ops && inode->u.i_ops->ioctl) { /* Yes, then let it perform the ioctl */ - ret = (int)inode->i_ops->ioctl(this_file, req, arg); + ret = (int)inode->u.i_ops->ioctl(this_file, req, arg); } } return ret; diff --git a/nuttx/fs/fs_open.c b/nuttx/fs/fs_open.c index 9b235f57b..0fc1b5133 100644 --- a/nuttx/fs/fs_open.c +++ b/nuttx/fs/fs_open.c @@ -60,8 +60,8 @@ int inode_checkflags(FAR struct inode *inode, int oflags) { - if (((oflags & O_RDOK) != 0 && !inode->i_ops->read) || - ((oflags & O_WROK) != 0 && !inode->i_ops->write)) + if (((oflags & O_RDOK) != 0 && !inode->u.i_ops->read) || + ((oflags & O_WROK) != 0 && !inode->u.i_ops->write)) { *get_errno_ptr() = EACCES; return ERROR; @@ -105,18 +105,29 @@ int open(const char *path, int oflags, ...) /* Get an inode for this file */ - inode = inode_find(path); + const char *relpath = NULL; + inode = inode_find(path, &relpath); if (!inode) { /* "O_CREAT is not set and the named file does not exist. Or, - * a directory component in pathname does not exist or is a - * dangling symbolic link. + * a directory component in pathname does not exist or is a + * dangling symbolic link." */ *get_errno_ptr() = ENOENT; return ERROR; } + /* Verify that the inode is either a "normal" or a mountpoint. We + * specifically exclude block drivers. + */ + + if (!INODE_IS_DRIVER(inode) && !INODE_IS_MOUNTPT(inode)) + { + *get_errno_ptr() = ENXIO; + return ERROR; + } + /* Make sure that the inode supports the requested access */ if (inode_checkflags(inode, oflags) != OK) @@ -138,12 +149,19 @@ int open(const char *path, int oflags, ...) /* Perform the driver open operation */ status = OK; - if (inode->i_ops && inode->i_ops->open) + if (inode->u.i_ops && inode->u.i_ops->open) { - status = inode->i_ops->open((FAR struct file*)&list->fl_files[fd]); + if (INODE_IS_MOUNTPT(inode)) + { + status = inode->u.i_ops->open((FAR struct file*)&list->fl_files[fd]); + } + else + { + status = inode->u.i_mops->open((FAR struct file*)&list->fl_files[fd], relpath); + } } - if (status != OK || !inode->i_ops) + if (status != OK || !inode->u.i_ops) { files_release(fd); inode_release(inode); diff --git a/nuttx/fs/fs_read.c b/nuttx/fs/fs_read.c index 7d0edb25e..d5a97c553 100644 --- a/nuttx/fs/fs_read.c +++ b/nuttx/fs/fs_read.c @@ -83,11 +83,11 @@ int read(int fd, void *buf, unsigned int nbytes) /* Is a driver registered? Does it support the read method? */ - if (inode && inode->i_ops && inode->i_ops->read) + if (inode && inode->u.i_ops && inode->u.i_ops->read) { /* Yes, then let it perform the read */ - ret = (int)inode->i_ops->read(this_file, (char*)buf, (size_t)nbytes); + ret = (int)inode->u.i_ops->read(this_file, (char*)buf, (size_t)nbytes); } } } diff --git a/nuttx/fs/fs_readdir.c b/nuttx/fs/fs_readdir.c index 034770c80..54a880328 100644 --- a/nuttx/fs/fs_readdir.c +++ b/nuttx/fs/fs_readdir.c @@ -104,7 +104,7 @@ FAR struct dirent *readdir(DIR *dirp) */ idir->dir.d_type = 0; - if (idir->next->i_ops) + if (idir->next->u.i_ops) { idir->dir.d_type |= DTYPE_FILE; } @@ -113,7 +113,7 @@ FAR struct dirent *readdir(DIR *dirp) * is a directory. NOTE: that the node can be both! */ - if (idir->next->i_child || !idir->next->i_ops) + if (idir->next->i_child || !idir->next->u.i_ops) { idir->dir.d_type |= DTYPE_DIRECTORY; } diff --git a/nuttx/fs/fs_registerblockdriver.c b/nuttx/fs/fs_registerblockdriver.c new file mode 100644 index 000000000..1e51deb37 --- /dev/null +++ b/nuttx/fs/fs_registerblockdriver.c @@ -0,0 +1,100 @@ +/************************************************************ + * fs_registerblockdriver.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include +#include +#include +#include +#include "fs_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Public Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: register_driver + ************************************************************/ + +STATUS register_blockdriver(const char *path, + const struct block_operations *bops, + mode_t mode, void *private) +{ + struct inode *node; + STATUS ret = ERROR; + + /* Insert a dummy node -- we need to hold the inode semaphore + * to do this because we will have a momentarily bad structure. + */ + + inode_semtake(); + node = inode_reserve(path); + if (node != NULL) + { + /* We have it, now populate it with block driver specific + * information. + */ + + INODE_SET_BLOCK(node); + + node->u.i_bops = bops; +#ifdef CONFIG_FILE_MODE + node->i_mode = mode; +#endif + node->i_private = private; + ret = OK; + } + inode_semgive(); + return ret; +} diff --git a/nuttx/fs/fs_registerdriver.c b/nuttx/fs/fs_registerdriver.c new file mode 100644 index 000000000..c92a05216 --- /dev/null +++ b/nuttx/fs/fs_registerdriver.c @@ -0,0 +1,101 @@ +/************************************************************ + * fs_registerdriver.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include +#include +#include +#include +#include "fs_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Public Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: register_driver + ************************************************************/ + +STATUS register_driver(const char *path, + const struct file_operations *fops, + mode_t mode, void *private) +{ + struct inode *node; + STATUS ret = ERROR; + + /* Insert a dummy node -- we need to hold the inode semaphore + * to do this because we will have a momentarily bad structure. + */ + + inode_semtake(); + node = inode_reserve(path); + if (node != NULL) + { + /* We have it, now populate it with driver specific + * information. + */ + + INODE_SET_DRIVER(node); + + node->u.i_ops = fops; +#ifdef CONFIG_FILE_MODE + node->i_mode = mode; +#endif + node->i_private = private; + ret = OK; + } + + inode_semgive(); + return ret; +} diff --git a/nuttx/fs/fs_registerinode.c b/nuttx/fs/fs_registerinode.c deleted file mode 100644 index a2d7892e4..000000000 --- a/nuttx/fs/fs_registerinode.c +++ /dev/null @@ -1,220 +0,0 @@ -/************************************************************ - * fs_registerinode.c - * - * Copyright (C) 2007 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name Gregory Nutt nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ************************************************************/ - -/************************************************************ - * Included Files - ************************************************************/ - -#include -#include -#include -#include -#include -#include "fs_internal.h" - -/************************************************************ - * Definitions - ************************************************************/ - -/************************************************************ - * Private Variables - ************************************************************/ - -/************************************************************ - * Public Variables - ************************************************************/ - -/************************************************************ - * Private Functions - ************************************************************/ - -/************************************************************ - * Name: inode_namelen - ************************************************************/ - -static int inode_namelen(const char *name) -{ - const char *tmp = name; - while(*tmp && *tmp != '/') tmp++; - return tmp - name; -} - -/************************************************************ - * Name: inode_namecpy - ************************************************************/ - -static void inode_namecpy(char *dest, const char *src) -{ - while(*src && *src != '/') *dest++ = *src++; - *dest='\0'; -} - -/************************************************************ - * Name: inode_alloc - ************************************************************/ - -static FAR struct inode *inode_alloc(const char *name, - struct file_operations *fops, - mode_t mode, void *private) -{ - int namelen = inode_namelen(name); - FAR struct inode *node = (FAR struct inode*)zalloc(FSNODE_SIZE(namelen)); - if (node) - { - node->i_ops = fops; -#ifdef CONFIG_FILE_MODE - node->i_mode = mode; -#endif - node->i_private = private; - inode_namecpy(node->i_name, name); - } - return node; -} - -/************************************************************ - * Name: inode_insert - ************************************************************/ - -static void inode_insert(FAR struct inode *node, - FAR struct inode *peer, - FAR struct inode *parent) -{ - /* If peer is non-null, then new node simply goes to the right - * of that peer node. - */ - - if (peer) - { - node->i_peer = peer->i_peer; - peer->i_peer = node; - } - - /* If parent is non-null, then it must go at the head of its - * list of children. - */ - - else if (parent) - { - node->i_peer = parent->i_child; - parent->i_child = node; - } - - /* Otherwise, this must be the new root_inode */ - - else - { - node->i_peer = root_inode; - root_inode = node; - } -} - -/************************************************************ - * Public Functions - ************************************************************/ - -/************************************************************ - * Name: register_inode - ************************************************************/ - -STATUS register_inode(const char *path, - struct file_operations *fops, - mode_t mode, void *private) -{ - const char *name = path; - FAR struct inode *left; - FAR struct inode *parent; - - if (!*path || path[0] != '/') - { - return ERROR; - } - - /* Find the location to insert the new subtree */ - - inode_semtake(); - if (inode_search(&name, &left, &parent) != NULL) - { - /* Is is an error if the node already exists in the tree */ - - inode_semgive(); - return ERROR; - } - - /* Now we now where to insert the subtree */ - - for (;;) - { - FAR struct inode *node; - - /* Create a new node -- we need to know if this is the - * the leaf node or some intermediary. We can find this - * by looking at the next name. - */ - - const char *next_name = inode_nextname(name); - if (*next_name) - { - /* Insert an operationless node */ - - node = inode_alloc(name, NULL, mode, NULL); - if (node) - { - inode_insert(node, left, parent); - - /* Set up for the next time through the loop */ - - name = next_name; - left = NULL; - parent = node; - continue; - } - } - else - { - node = inode_alloc(name, fops, mode, private); - if (node) - { - inode_insert(node, left, parent); - inode_semgive(); - return 0; - } - } - - /* We get here on failures to allocate node memory */ - - inode_semgive(); - return ERROR; - } -} diff --git a/nuttx/fs/fs_unregisterinode.c b/nuttx/fs/fs_unregisterinode.c deleted file mode 100644 index 37fd538ce..000000000 --- a/nuttx/fs/fs_unregisterinode.c +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************ - * fs_unregisterinode.c - * - * Copyright (C) 2007 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name Gregory Nutt nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ************************************************************/ - -/************************************************************ - * Included Files - ************************************************************/ - -#include -#include -#include -#include -#include -#include "fs_internal.h" - -/************************************************************ - * Definitions - ************************************************************/ - -/************************************************************ - * Private Variables - ************************************************************/ - -/************************************************************ - * Public Variables - ************************************************************/ - -/************************************************************ - * Private Functions - ************************************************************/ - -/************************************************************ - * Name: inode_remove - ************************************************************/ - -static void inode_remove(struct inode *node, - struct inode *peer, - struct inode *parent) -{ - /* If peer is non-null, then remove the node from the right of - * of that peer node. - */ - - if (peer) - { - peer->i_peer = node->i_peer; - } - - /* If parent is non-null, then remove the node from head of - * of the list of children. - */ - - else if (parent) - { - parent->i_child = node->i_peer; - } - - /* Otherwise, we must be removing the root inode. */ - - else - { - root_inode = node->i_peer; - } - node->i_peer = NULL; -} - -/************************************************************ - * Public Functions - ************************************************************/ - -/************************************************************ - * Name: unregister_inode - ************************************************************/ - -STATUS unregister_inode(const char *path) -{ - const char *name = path; - FAR struct inode *node; - FAR struct inode *left; - FAR struct inode *parent; - - if (*path && path[0] == '/') - { - return ERROR; - } - - /* Find the node to delete */ - - inode_semtake(); - node = inode_search(&name, &left, &parent); - if (node) - { - /* Found it, now remove it from the tree */ - - inode_remove(node, left, parent); - - /* We cannot delete it if there reference to the inode */ - - if (node->i_crefs) - { - /* In that case, we will mark it deleted, when the FS - * releases the inode, we will then, finally delete - * the subtree. - */ - - node->i_flags |= FSNODEFLAG_DELETED; - inode_semgive(); - } - else - { - /* And delete it now -- recursively to delete all of its children */ - - inode_semgive(); - inode_free(node->i_child); - free(node); - return OK; - } - } - - /* The node does not exist or it has references */ - - inode_semgive(); - return ERROR; -} diff --git a/nuttx/fs/fs_write.c b/nuttx/fs/fs_write.c index d25a88489..cebb49e60 100644 --- a/nuttx/fs/fs_write.c +++ b/nuttx/fs/fs_write.c @@ -83,11 +83,11 @@ int write(int fd, const void *buf, unsigned int nbytes) /* Is a driver registered? Does it support the write method? */ - if (inode && inode->i_ops && inode->i_ops->write) + if (inode && inode->u.i_ops && inode->u.i_ops->write) { /* Yes, then let it perform the write */ - ret = inode->i_ops->write(this_file, buf, nbytes); + ret = inode->u.i_ops->write(this_file, buf, nbytes); } } } -- cgit v1.2.3