fs: add pipe type support to inode

Both the device and the pipe used the FSNODEFLAG_TYPE_DRIVER type before,
and now add an independent pipe type

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
yinshengkai 2023-06-07 21:57:30 +08:00 committed by Xiang Xiao
parent 25eb09c3bb
commit a6fcb0a5a9
13 changed files with 237 additions and 22 deletions

View file

@ -106,7 +106,7 @@ int nx_mkfifo(FAR const char *pathname, mode_t mode, size_t bufsize)
return -ENOMEM;
}
ret = register_driver(pathname, &g_fifo_fops, mode, (FAR void *)dev);
ret = register_pipedriver(pathname, &g_fifo_fops, mode, (FAR void *)dev);
if (ret != 0)
{
pipecommon_freedev(dev);

View file

@ -171,7 +171,7 @@ static int pipe_register(size_t bufsize, int flags,
/* Register the pipe device */
ret = register_driver(devname, &g_pipe_fops, 0666, (FAR void *)dev);
ret = register_pipedriver(devname, &g_pipe_fops, 0666, (FAR void *)dev);
if (ret != 0)
{
pipecommon_freedev(dev);
@ -251,14 +251,14 @@ int file_pipe(FAR struct file *filep[2], size_t bufsize, int flags)
/* Remove the pipe name from file system */
unregister_driver(devname);
unregister_pipedriver(devname);
return OK;
errout_with_wrfd:
file_close(filep[1]);
errout_with_driver:
unregister_driver(devname);
unregister_pipedriver(devname);
return ret;
}
@ -329,14 +329,14 @@ int pipe2(int fd[2], int flags)
/* Remove the pipe name from file system */
unregister_driver(devname);
unregister_pipedriver(devname);
return OK;
errout_with_wrfd:
nx_close(fd[1]);
errout_with_driver:
unregister_driver(devname);
unregister_pipedriver(devname);
return ERROR;
}

View file

@ -37,17 +37,6 @@
* Pre-processor Definitions
****************************************************************************/
/* Pipe/FIFO support */
#ifndef CONFIG_PIPES
# undef CONFIG_DEV_PIPE_MAXSIZE
# undef CONFIG_DEV_PIPE_SIZE
# undef CONFIG_DEV_FIFO_SIZE
# define CONFIG_DEV_PIPE_MAXSIZE 0
# define CONFIG_DEV_PIPE_SIZE 0
# define CONFIG_DEV_FIFO_SIZE 0
#endif
/* Pipe/FIFO size */
#ifndef CONFIG_DEV_PIPE_MAXSIZE
@ -70,6 +59,17 @@
# define CONFIG_DEV_FIFO_SIZE 1024
#endif
/* Pipe/FIFO support */
#ifndef CONFIG_PIPES
# undef CONFIG_DEV_PIPE_MAXSIZE
# undef CONFIG_DEV_PIPE_SIZE
# undef CONFIG_DEV_FIFO_SIZE
# define CONFIG_DEV_PIPE_MAXSIZE 0
# define CONFIG_DEV_PIPE_SIZE 0
# define CONFIG_DEV_FIFO_SIZE 0
#endif
/* Maximum number of threads than can be waiting for POLL events */
#ifndef CONFIG_DEV_PIPE_NPOLLWAITERS

View file

@ -18,7 +18,8 @@
#
# ##############################################################################
set(SRCS fs_registerdriver.c fs_unregisterdriver.c)
set(SRCS fs_registerdriver.c fs_unregisterdriver.c fs_registerpipedriver.c
fs_unregisterpipedriver.c)
# Don't built-in block driver support if there are no mountpoints

View file

@ -19,6 +19,7 @@
############################################################################
CSRCS += fs_registerdriver.c fs_unregisterdriver.c
CSRCS += fs_registerpipedriver.c fs_unregisterpipedriver.c
# Don't built-in block driver support if there are no mountpoints

View file

@ -0,0 +1,98 @@
/****************************************************************************
* fs/driver/fs_registerpipedriver.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <errno.h>
#include <nuttx/fs/fs.h>
#include "inode/inode.h"
#ifdef CONFIG_PIPES
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: register_pipedriver
*
* Description:
* Register a pipe driver inode the pseudo file system.
*
* Input Parameters:
* path - The path to the inode to create
* fops - The file operations structure
* mode - inmode privileges
* priv - Private, user data that will be associated with the inode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/
int register_pipedriver(FAR const char *path,
FAR const struct file_operations *fops,
mode_t mode, FAR void *priv)
{
FAR struct inode *node;
int ret;
/* Insert a dummy node -- we need to hold the inode semaphore because we
* will have a momentarily bad structure.
*/
ret = inode_lock();
if (ret < 0)
{
return ret;
}
ret = inode_reserve(path, mode, &node);
if (ret >= 0)
{
/* We have it, now populate it with driver specific information.
* NOTE that the initial reference count on the new inode is zero.
*/
INODE_SET_PIPE(node);
node->u.i_ops = fops;
node->i_private = priv;
ret = OK;
}
inode_unlock();
return ret;
}
#endif /* CONFIG_PIPES */

View file

@ -0,0 +1,59 @@
/****************************************************************************
* fs/driver/fs_unregisterpipedriver.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/fs/fs.h>
#include "inode/inode.h"
#ifdef CONFIG_PIPES
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: unregister_pipedriver
*
* Description:
* Remove the pipe driver inode at 'path' from the pseudo-file system
*
****************************************************************************/
int unregister_pipedriver(FAR const char *path)
{
int ret;
ret = inode_lock();
if (ret >= 0)
{
ret = inode_remove(path);
inode_unlock();
}
return ret;
}
#endif /* CONFIG_PIPES */

View file

@ -355,6 +355,10 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir,
{
entry->d_type = DTYPE_SHM;
}
else if (INODE_IS_PIPE(pdir->next))
{
entry->d_type = DTYPE_FIFO;
}
}
/* If the node has child node(s) or no operations, then we will say that

View file

@ -188,7 +188,7 @@ static int file_vopen(FAR struct file *filep, FAR const char *path,
}
}
#endif
else if (INODE_IS_DRIVER(inode))
else if (INODE_IS_DRIVER(inode) || INODE_IS_PIPE(inode))
{
if (inode->u.i_ops->open != NULL)
{

View file

@ -307,7 +307,7 @@ int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
*/
if ((INODE_IS_DRIVER(inode) || INODE_IS_MQUEUE(inode) ||
INODE_IS_SOCKET(inode)) &&
INODE_IS_SOCKET(inode) || INODE_IS_PIPE(inode)) &&
inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL)
{
/* Yes, it does... Setup the poll */

View file

@ -360,7 +360,15 @@ int inode_stat(FAR struct inode *inode, FAR struct stat *buf, int resolve)
}
else
#endif
#if defined(CONFIG_PIPES)
/* Check for pipes */
if (INODE_IS_PIPE(inode))
{
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFIFO;
}
else
#endif
/* Handle "normal inodes */
if (inode->u.i_ops != NULL)

View file

@ -123,8 +123,8 @@ int nx_unlink(FAR const char *pathname)
* release all resources because it is no longer accessible.
*/
if ((INODE_IS_DRIVER(inode) || INODE_IS_SHM(inode)) &&
inode->u.i_ops->unlink)
if ((INODE_IS_DRIVER(inode) || INODE_IS_SHM(inode) ||
INODE_IS_PIPE(inode)) && inode->u.i_ops->unlink)
{
/* Notify the character driver that it has been unlinked */

View file

@ -114,6 +114,7 @@
#define FSNODEFLAG_TYPE_MTD 0x00000007 /* Named MTD driver */
#define FSNODEFLAG_TYPE_SOFTLINK 0x00000008 /* Soft link */
#define FSNODEFLAG_TYPE_SOCKET 0x00000009 /* Socket */
#define FSNODEFLAG_TYPE_PIPE 0x0000000a /* Pipe */
#define FSNODEFLAG_DELETED 0x00000010 /* Unlinked */
#define INODE_IS_TYPE(i,t) \
@ -129,6 +130,7 @@
#define INODE_IS_MTD(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MTD)
#define INODE_IS_SOFTLINK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK)
#define INODE_IS_SOCKET(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOCKET)
#define INODE_IS_PIPE(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_PIPE)
#define INODE_GET_TYPE(i) ((i)->i_flags & FSNODEFLAG_TYPE_MASK)
#define INODE_SET_TYPE(i,t) \
@ -147,6 +149,7 @@
#define INODE_SET_MTD(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MTD)
#define INODE_SET_SOFTLINK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK)
#define INODE_SET_SOCKET(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOCKET)
#define INODE_SET_PIPE(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_PIPE)
/* The status change flags.
* These should be or-ed together to figure out what want to change.
@ -718,6 +721,47 @@ int register_mtdpartition(FAR const char *partition,
int unregister_mtddriver(FAR const char *path);
#endif
#ifdef CONFIG_PIPES
/****************************************************************************
* Name: register_pipedriver
*
* Description:
* Register a pipe driver inode the pseudo file system.
*
* Input Parameters:
* path - The path to the inode to create
* fops - The file operations structure
* mode - inmode privileges
* priv - Private, user data that will be associated with the inode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/
int register_pipedriver(FAR const char *path,
FAR const struct file_operations *fops,
mode_t mode, FAR void *priv);
/****************************************************************************
* Name: unregister_pipedriver
*
* Description:
* Remove the pipe driver inode at 'path' from the pseudo-file system
*
****************************************************************************/
int unregister_pipedriver(FAR const char *path);
#endif /* CONFIG_PIPES */
/****************************************************************************
* Name: nx_mount
*