mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 10:46:28 +08:00
vfs: Create a node as the root of pseudo file system
to remove the special process for root Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
committed by
David Sidrane
parent
e2fd1fdd84
commit
b76c4672d6
+16
-40
@@ -218,7 +218,6 @@ FAR DIR *opendir(FAR const char *path)
|
|||||||
FAR const char *relpath = NULL;
|
FAR const char *relpath = NULL;
|
||||||
#endif
|
#endif
|
||||||
FAR char *alloc = NULL;
|
FAR char *alloc = NULL;
|
||||||
bool isroot = false;
|
|
||||||
int len;
|
int len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -277,32 +276,24 @@ FAR DIR *opendir(FAR const char *path)
|
|||||||
goto errout_with_alloc;
|
goto errout_with_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == NULL || *path == '\0' || strcmp(path, "/") == 0)
|
/* We don't know what to do with relative paths */
|
||||||
|
|
||||||
|
if (*path != '/')
|
||||||
{
|
{
|
||||||
inode = g_root_inode;
|
ret = ENOTDIR;
|
||||||
isroot = true;
|
goto errout_with_semaphore;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* Find the node matching the path. */
|
||||||
|
|
||||||
|
ret = inode_search(&desc);
|
||||||
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
/* We don't know what to do with relative paths */
|
inode = desc.node;
|
||||||
|
DEBUGASSERT(inode != NULL);
|
||||||
if (*path != '/')
|
|
||||||
{
|
|
||||||
ret = ENOTDIR;
|
|
||||||
goto errout_with_semaphore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the node matching the path. */
|
|
||||||
|
|
||||||
ret = inode_search(&desc);
|
|
||||||
if (ret >= 0)
|
|
||||||
{
|
|
||||||
inode = desc.node;
|
|
||||||
DEBUGASSERT(inode != NULL);
|
|
||||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||||
relpath = desc.relpath;
|
relpath = desc.relpath;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did we get an inode? */
|
/* Did we get an inode? */
|
||||||
@@ -335,25 +326,10 @@ FAR DIR *opendir(FAR const char *path)
|
|||||||
|
|
||||||
dir->fd_position = 0; /* This is the position in the read stream */
|
dir->fd_position = 0; /* This is the position in the read stream */
|
||||||
|
|
||||||
/* First, handle the special case of the root inode. This must be
|
/* Is this a node in the pseudo filesystem? Or a mountpoint? */
|
||||||
* special-cased here because the root inode might ALSO be a mountpoint.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (isroot)
|
|
||||||
{
|
|
||||||
/* Whatever payload the root inode carries, the root inode is always
|
|
||||||
* a directory inode in the pseudo-file system
|
|
||||||
*/
|
|
||||||
|
|
||||||
open_pseudodir(inode, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this a node in the pseudo filesystem? Or a mountpoint? If the node
|
|
||||||
* is the root (isroot == TRUE), then this is a special case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||||
else if (INODE_IS_MOUNTPT(inode))
|
if (INODE_IS_MOUNTPT(inode))
|
||||||
{
|
{
|
||||||
/* Yes, the node is a file system mountpoint */
|
/* Yes, the node is a file system mountpoint */
|
||||||
|
|
||||||
@@ -367,8 +343,8 @@ FAR DIR *opendir(FAR const char *path)
|
|||||||
goto errout_with_direntry;
|
goto errout_with_direntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* The node is part of the root pseudo file system. Does the inode
|
/* The node is part of the root pseudo file system. Does the inode
|
||||||
* have a child? If so that the child would be the 'root' of a list
|
* have a child? If so that the child would be the 'root' of a list
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ void inode_initialize(void)
|
|||||||
g_inode_sem.holder = NO_HOLDER;
|
g_inode_sem.holder = NO_HOLDER;
|
||||||
g_inode_sem.count = 0;
|
g_inode_sem.count = 0;
|
||||||
|
|
||||||
|
/* Reserve the root node */
|
||||||
|
|
||||||
|
inode_root_reserve();
|
||||||
|
|
||||||
/* Initialize files array (if it is used) */
|
/* Initialize files array (if it is used) */
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
|
|||||||
@@ -100,20 +100,12 @@ FAR struct inode *inode_unlink(FAR const char *path)
|
|||||||
desc.peer->i_peer = node->i_peer;
|
desc.peer->i_peer = node->i_peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If parent is non-null, then remove the node from head of
|
/* Then remove the node from head of the list of children. */
|
||||||
* of the list of children.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if (desc.parent)
|
|
||||||
{
|
|
||||||
desc.parent->i_child = node->i_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, we must be removing the root inode. */
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_root_inode = node->i_peer;
|
DEBUGASSERT(desc.parent != NULL);
|
||||||
|
desc.parent->i_child = node->i_peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->i_peer = NULL;
|
node->i_peer = NULL;
|
||||||
@@ -162,7 +154,8 @@ int inode_remove(FAR const char *path)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* And delete it now -- recursively to delete all of its children.
|
/* And delete it now -- recursively to delete all of its children.
|
||||||
* Since it has been unlinked, then the peer pointer should be NULL.
|
* Since it has been unlinked, then the peer pointer should be
|
||||||
|
* NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(node->i_peer == NULL);
|
DEBUGASSERT(node->i_peer == NULL);
|
||||||
|
|||||||
+18
-14
@@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/inode/fs_registerreserve.c
|
* fs/inode/fs_inodereserve.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011-2012, 2015, 2017 Gregory Nutt. All
|
* Copyright (C) 2007-2009, 2011-2012, 2015, 2017 Gregory Nutt. All
|
||||||
* rights reserved.
|
* rights reserved.
|
||||||
@@ -118,22 +118,13 @@ static void inode_insert(FAR struct inode *node,
|
|||||||
peer->i_peer = node;
|
peer->i_peer = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If parent is non-null, then it must go at the head of its
|
/* Then it must go at the head of parent's list of children. */
|
||||||
* 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
|
else
|
||||||
{
|
{
|
||||||
node->i_peer = g_root_inode;
|
DEBUGASSERT(parent != NULL);
|
||||||
g_root_inode = node;
|
node->i_peer = parent->i_child;
|
||||||
|
parent->i_child = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +132,19 @@ static void inode_insert(FAR struct inode *node,
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: inode_root_reserve
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Reserve the root inode for the pseudo file system.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void inode_root_reserve(void)
|
||||||
|
{
|
||||||
|
g_root_inode = inode_alloc("");
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: inode_reserve
|
* Name: inode_reserve
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/inode/fs_inodesearch.c
|
* fs/inode/fs_inodesearch.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011-2012, 2016-2017 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011-2012, 2016-2017 Gregory Nutt.
|
||||||
|
* All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -255,24 +256,6 @@ static int _inode_search(FAR struct inode_search_s *desc)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip over the leading '/' */
|
|
||||||
|
|
||||||
while (*name == '/')
|
|
||||||
{
|
|
||||||
name++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special case the root directory. There is no root inode and there is
|
|
||||||
* no name for the root.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (*name == '\0')
|
|
||||||
{
|
|
||||||
/* This is a bug. I don't know how to handle this case yet. */
|
|
||||||
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Traverse the pseudo file system node tree until either (1) all nodes
|
/* Traverse the pseudo file system node tree until either (1) all nodes
|
||||||
* have been examined without finding the matching node, or (2) the
|
* have been examined without finding the matching node, or (2) the
|
||||||
* matching node is found.
|
* matching node is found.
|
||||||
@@ -347,7 +330,8 @@ static int _inode_search(FAR struct inode_search_s *desc)
|
|||||||
/* If this intermediate inode in the is a soft link, then
|
/* If this intermediate inode in the is a soft link, then
|
||||||
* (1) get the name of the full path of the soft link, (2)
|
* (1) get the name of the full path of the soft link, (2)
|
||||||
* recursively look-up the inode referenced by the soft
|
* recursively look-up the inode referenced by the soft
|
||||||
* link, and (3) continue searching with that inode instead.
|
* link, and (3) continue searching with that inode
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status = _inode_linktarget(node, desc);
|
status = _inode_linktarget(node, desc);
|
||||||
|
|||||||
@@ -283,6 +283,16 @@ void inode_free(FAR struct inode *node);
|
|||||||
|
|
||||||
const char *inode_nextname(FAR const char *name);
|
const char *inode_nextname(FAR const char *name);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: inode_root_reserve
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Reserve the root node for the pseudo file system.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void inode_root_reserve(void);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: inode_reserve
|
* Name: inode_reserve
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -65,40 +65,8 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode,
|
|||||||
struct inode_search_s newdesc;
|
struct inode_search_s newdesc;
|
||||||
FAR struct inode *newinode;
|
FAR struct inode *newinode;
|
||||||
FAR char *subdir = NULL;
|
FAR char *subdir = NULL;
|
||||||
FAR const char *name;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Special case the root directory. There is no root inode and there is
|
|
||||||
* no name for the root. inode_find() will fail to the find the root
|
|
||||||
* inode -- because there isn't one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
name = newpath;
|
|
||||||
while (*name == '/')
|
|
||||||
{
|
|
||||||
name++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*name == '\0')
|
|
||||||
{
|
|
||||||
FAR char *subdirname;
|
|
||||||
|
|
||||||
/* In the newpath is the root directory, the target of the rename must
|
|
||||||
* be a directory entry under the root.
|
|
||||||
*/
|
|
||||||
|
|
||||||
subdirname = basename((FAR char *)oldpath);
|
|
||||||
|
|
||||||
asprintf(&subdir, "/%s", subdirname);
|
|
||||||
if (subdir == NULL)
|
|
||||||
{
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
newpath = subdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* According to POSIX, any old inode at this path should be removed
|
/* According to POSIX, any old inode at this path should be removed
|
||||||
* first, provided that it is not a directory.
|
* first, provided that it is not a directory.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -57,7 +57,6 @@
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline int statroot(FAR struct stat *buf);
|
|
||||||
static int stat_recursive(FAR const char *path,
|
static int stat_recursive(FAR const char *path,
|
||||||
FAR struct stat *buf, int resolve);
|
FAR struct stat *buf, int resolve);
|
||||||
|
|
||||||
@@ -65,19 +64,6 @@ static int stat_recursive(FAR const char *path,
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: statroot
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline int statroot(FAR struct stat *buf)
|
|
||||||
{
|
|
||||||
/* There is no inode associated with the fake root directory */
|
|
||||||
|
|
||||||
RESET_BUF(buf);
|
|
||||||
buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: stat_recursive
|
* Name: stat_recursive
|
||||||
*
|
*
|
||||||
@@ -187,13 +173,6 @@ int nx_stat(FAR const char *path, FAR struct stat *buf, int resolve)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for the fake root directory (which has no inode) */
|
|
||||||
|
|
||||||
if (strcmp(path, "/") == 0)
|
|
||||||
{
|
|
||||||
return statroot(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The perform the stat() operation on the path. This is potentially
|
/* The perform the stat() operation on the path. This is potentially
|
||||||
* recursive if soft link support is enabled.
|
* recursive if soft link support is enabled.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -104,13 +104,6 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for the fake root directory (which has no inode) */
|
|
||||||
|
|
||||||
if (strcmp(path, "/") == 0)
|
|
||||||
{
|
|
||||||
return statpseudofs(NULL, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get an inode for this file */
|
/* Get an inode for this file */
|
||||||
|
|
||||||
SETUP_SEARCH(&desc, path, false);
|
SETUP_SEARCH(&desc, path, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user