Description:vfs refactoring

Feature or Bugfix:Feature
Binary Source:Huawei
PrivateCode(Yes/No):Yes

Change-Id: I175d2648bc6f9078c34de2c0a5c93fda10b86c47
ChangeID:13306420
This commit is contained in:
wangchenyang
2021-01-15 05:26:30 +08:00
committed by mamingshuai
parent eabbc1eb3d
commit 70bdb2590c
64 changed files with 5278 additions and 7348 deletions
+1 -1
View File
@@ -62,7 +62,7 @@
struct bchlib_s
{
struct inode *inode; /* I-node of the block driver */
struct Vnode *vnode; /* I-node of the block driver */
uint32_t sectsize; /* The size of one sector on the device */
unsigned long long nsectors; /* Number of sectors supported by the device */
unsigned long long sector; /* The current sector in the buffer */
Executable → Regular
+43 -55
View File
@@ -68,7 +68,7 @@ static ssize_t bch_write(struct file *filep, const char *buffer,
static int bch_ioctl(struct file *filep, int cmd,
unsigned long arg);
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int bch_unlink(struct inode *inode);
static int bch_unlink(struct Vnode *vnode);
#endif
/****************************************************************************
@@ -77,17 +77,13 @@ static int bch_unlink(struct inode *inode);
const struct file_operations_vfs bch_fops =
{
bch_open, /* open */
bch_close, /* close */
bch_read, /* read */
bch_write, /* write */
bch_seek, /* seek */
bch_ioctl, /* ioctl */
NULL, /* mmap */
#ifndef CONFIG_DISABLE_POLL
NULL, /* poll */
#endif
bch_unlink, /* unlink */
.open = bch_open, /* open */
.close = bch_close, /* close */
.read = bch_read, /* read */
.write = bch_write, /* write */
.seek = bch_seek, /* seek */
.ioctl = bch_ioctl, /* ioctl */
.unlink = bch_unlink, /* unlink */
};
/****************************************************************************
@@ -101,14 +97,13 @@ const struct file_operations_vfs bch_fops =
*
****************************************************************************/
static int bch_open(FAR struct file *filep)
static int bch_open(struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bchlib_s *bch;
struct Vnode *vnode = filep->f_vnode;
struct bchlib_s *bch;
int ret = OK;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
/* Increment the reference count */
@@ -133,14 +128,13 @@ static int bch_open(FAR struct file *filep)
*
****************************************************************************/
static int bch_close(FAR struct file *filep)
static int bch_close(struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bchlib_s *bch;
struct Vnode *vnode = filep->f_vnode;
struct bchlib_s *bch;
int ret = OK;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
/* Flush any dirty pages remaining in the cache */
@@ -168,7 +162,7 @@ static int bch_close(FAR struct file *filep)
{
/* Tear the driver down now. */
ret = bchlib_teardown((FAR void *)bch);
ret = bchlib_teardown((void *)bch);
/* bchlib_teardown() would only fail if there are outstanding
* references on the device. Since we know that is not true, it
@@ -193,16 +187,14 @@ static int bch_close(FAR struct file *filep)
* Name: bch_seek
****************************************************************************/
static off_t bch_seek(FAR struct file *filep, off_t offset, int whence)
static off_t bch_seek(struct file *filep, off_t offset, int whence)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bchlib_s *bch;
struct Vnode *vnode = filep->f_vnode;
struct bchlib_s *bch;
loff_t newpos;
int ret;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
bchlib_semtake(bch);
/* Determine the new, requested file position */
@@ -259,14 +251,13 @@ static off_t bch_seek(FAR struct file *filep, off_t offset, int whence)
* Name: bch_read
****************************************************************************/
static ssize_t bch_read(FAR struct file *filep, FAR char *buffer, size_t len)
static ssize_t bch_read(struct file *filep, char *buffer, size_t len)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bchlib_s *bch;
struct Vnode *vnode = filep->f_vnode;
struct bchlib_s *bch;
int ret;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
bchlib_semtake(bch);
ret = bchlib_read(bch, buffer, filep->f_pos, len);
@@ -283,14 +274,13 @@ static ssize_t bch_read(FAR struct file *filep, FAR char *buffer, size_t len)
* Name: bch_write
****************************************************************************/
static ssize_t bch_write(FAR struct file *filep, FAR const char *buffer, size_t len)
static ssize_t bch_write(struct file *filep, const char *buffer, size_t len)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bchlib_s *bch;
struct Vnode *vnode = filep->f_vnode;
struct bchlib_s *bch;
int ret = -EACCES;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
if (!bch->readonly)
{
@@ -315,14 +305,14 @@ static ssize_t bch_write(FAR struct file *filep, FAR const char *buffer, size_t
*
****************************************************************************/
static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
static int bch_ioctl(struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bchlib_s *bch;
struct Vnode *vnode = filep->f_vnode;
struct bchlib_s *bch;
struct block_operations *bop = NULL;
int ret = -ENOTTY;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
/* Process the call according to the command */
@@ -332,8 +322,8 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
case DIOC_GETPRIV:
{
FAR struct bchlib_s **bchr =
(FAR struct bchlib_s **)((uintptr_t)arg);
struct bchlib_s **bchr =
(struct bchlib_s **)((uintptr_t)arg);
bchlib_semtake(bch);
if (!bchr || bch->refs == MAX_OPENCNT)
@@ -362,8 +352,6 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
default:
{
struct inode *bchinode = bch->inode;
/* Does the block driver support the ioctl method? */
los_disk *disk = bch->disk;
@@ -380,9 +368,10 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
if (disk->disk_status == STAT_INUSED)
{
if (bchinode->u.i_bops->ioctl != NULL)
bop = (struct block_operations *)(((struct drv_data *)vnode->data)->ops);
if (bop != NULL && bop->ioctl != NULL)
{
ret = bchinode->u.i_bops->ioctl(bchinode, cmd, arg);
ret = bop->ioctl(bch->vnode, cmd, arg);
}
}
@@ -405,13 +394,12 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
*
****************************************************************************/
static int bch_unlink(FAR struct inode *inode)
int bch_unlink(struct Vnode *vnode)
{
FAR struct bchlib_s *bch;
struct bchlib_s *bch;
int ret = OK;
DEBUGASSERT(inode && inode->i_private);
bch = (FAR struct bchlib_s *)inode->i_private;
bch = (struct bchlib_s *)((struct drv_data *)vnode->data)->priv;
/* Get exclusive access to the BCH device */
@@ -429,7 +417,7 @@ static int bch_unlink(FAR struct inode *inode)
{
/* Tear the driver down now. */
ret = bchlib_teardown((FAR void *)bch);
ret = bchlib_teardown((void *)bch);
/* bchlib_teardown() would only fail if there are outstanding
* references on the device. Since we know that is not true, it
Executable → Regular
+12 -10
View File
@@ -60,9 +60,9 @@
*
****************************************************************************/
int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle)
int bchlib_setup(const char *blkdev, bool readonly, void **handle)
{
FAR struct bchlib_s *bch;
struct bchlib_s *bch;
struct geometry geo;
los_part *part;
int ret;
@@ -71,26 +71,28 @@ int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle)
/* Allocate the BCH state structure */
bch = (FAR struct bchlib_s *)zalloc(sizeof(struct bchlib_s));
bch = (struct bchlib_s *)zalloc(sizeof(struct bchlib_s));
if (!bch)
{
PRINTK("ERROR: Failed to allocate BCH structure\n");
return -ENOMEM;
}
/* Open the block driver */
ret = open_blockdriver(blkdev, readonly ? MS_RDONLY : 0, &bch->inode);
ret = open_blockdriver(blkdev, readonly ? MS_RDONLY : 0, &bch->vnode);
if (ret < 0)
{
PRINTK("ERROR: Failed to open driver %s: %d\n", blkdev, -ret);
goto errout_with_bch;
}
DEBUGASSERT(bch->inode && bch->inode->u.i_bops && bch->inode->u.i_bops->geometry);
struct drv_data *drv = (struct drv_data *)bch->vnode->data;
struct block_operations *bops = (struct block_operations *)drv->ops;
ret = bch->inode->u.i_bops->geometry(bch->inode, &geo);
DEBUGASSERT(bch->vnode && bops && bops->geometry);
ret = bops->geometry(bch->vnode, &geo);
if (ret < 0)
{
PRINTK("ERROR: geometry failed: %d\n", -ret);
@@ -104,7 +106,7 @@ int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle)
goto errout_with_bch;
}
if (!readonly && (!bch->inode->u.i_bops->write || !geo.geo_writeenabled))
if (!readonly && (!bops->write || !geo.geo_writeenabled))
{
PRINTK("ERROR: write access not supported\n");
ret = -EACCES;
@@ -121,7 +123,7 @@ int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle)
bch->dirty = false;
bch->unlinked = false;
part = los_part_find(bch->inode);
part = los_part_find(bch->vnode);
if (part != NULL)
{
bch->sectstart = part->sector_start;
@@ -137,7 +139,7 @@ int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle)
/* Allocate the sector I/O buffer */
bch->buffer = (FAR uint8_t *)malloc(bch->sectsize);
bch->buffer = (uint8_t *)malloc(bch->sectsize);
if (!bch->buffer)
{
PRINTK("ERROR: Failed to allocate sector buffer\n");
Executable → Regular
+4 -3
View File
@@ -40,6 +40,7 @@
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include "fs/fs.h"
#include "bch.h"
/****************************************************************************
@@ -55,9 +56,9 @@
*
****************************************************************************/
int bchlib_teardown(FAR void *handle)
int bchlib_teardown(void *handle)
{
FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
struct bchlib_s *bch = (struct bchlib_s *)handle;
DEBUGASSERT(handle);
@@ -74,7 +75,7 @@ int bchlib_teardown(FAR void *handle)
/* Close the block driver */
(void)close_blockdriver(bch->inode);
(void)close_blockdriver(bch->vnode);
/* Free the BCH state structure */
Executable → Regular
+13 -13
View File
@@ -51,7 +51,7 @@
* Private Data
****************************************************************************/
static ssize_t fifo_map(FAR struct file* filep, FAR LosVmMapRegion *region)
static ssize_t fifo_map(struct file* filep, LosVmMapRegion *region)
{
PRINTK("%s %d, mmap is not support\n", __FUNCTION__, __LINE__);
return 0;
@@ -59,16 +59,16 @@ static ssize_t fifo_map(FAR struct file* filep, FAR LosVmMapRegion *region)
static const struct file_operations_vfs fifo_fops =
{
pipecommon_open, /* open */
pipecommon_close, /* close */
pipecommon_read, /* read */
pipecommon_write, /* write */
NULL, /* seek */
NULL, /* ioctl */
fifo_map, /* mmap */
NULL, /* poll */
.open = pipecommon_open, /* open */
.close = pipecommon_close, /* close */
.read = pipecommon_read, /* read */
.write = pipecommon_write, /* write */
.seek = NULL, /* seek */
.ioctl = NULL, /* ioctl */
.mmap = fifo_map, /* mmap */
.poll = NULL, /* poll */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
pipecommon_unlink, /* unlink */
.unlink = pipecommon_unlink, /* unlink */
#endif
};
@@ -110,9 +110,9 @@ static const struct file_operations_vfs fifo_fops =
*
****************************************************************************/
int mkfifo(FAR const char *pathname, mode_t mode)
int mkfifo(const char *pathname, mode_t mode)
{
FAR struct pipe_dev_s *dev;
struct pipe_dev_s *dev = NULL;
int ret;
size_t bufsize = 1024;
@@ -139,7 +139,7 @@ int mkfifo(FAR const char *pathname, mode_t mode)
return -ENOMEM;
}
ret = register_driver(pathname, &fifo_fops, mode, (FAR void *)dev);
ret = register_driver(pathname, &fifo_fops, mode, (void *)dev);
if (ret != 0)
{
pipecommon_freedev(dev);
Executable → Regular
+31 -24
View File
@@ -47,6 +47,7 @@
#include <fs/fs.h>
#include "fs/vnode.h"
#include "pipe_common.h"
#include "stdio.h"
#if CONFIG_DEV_PIPE_SIZE > 0
@@ -65,16 +66,16 @@
* Private Function Prototypes
****************************************************************************/
static int pipe_close(FAR struct file *filep);
static int pipe_close(struct file *filep);
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int pipe_unlink(FAR struct inode *priv);
int pipe_unlink(struct Vnode *priv);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static ssize_t pipe_map(FAR struct file* filep, FAR LosVmMapRegion *region)
static ssize_t pipe_map(struct file* filep, LosVmMapRegion *region)
{
PRINTK("%s %d, mmap is not support\n", __FUNCTION__, __LINE__);
return 0;
@@ -82,16 +83,16 @@ static ssize_t pipe_map(FAR struct file* filep, FAR LosVmMapRegion *region)
static const struct file_operations_vfs pipe_fops =
{
pipecommon_open, /* open */
pipe_close, /* close */
pipecommon_read, /* read */
pipecommon_write, /* write */
NULL, /* seek */
NULL, /* ioctl */
pipe_map, /* mmap */
pipecommon_poll, /* poll */
.open = pipecommon_open, /* open */
.close = pipe_close, /* close */
.read = pipecommon_read, /* read */
.write = pipecommon_write, /* write */
.seek = NULL, /* seek */
.ioctl = NULL, /* ioctl */
.mmap = pipe_map, /* mmap */
.poll = pipecommon_poll, /* poll */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
pipe_unlink, /* unlink */
.unlink = pipe_unlink, /* unlink */
#endif
};
@@ -145,10 +146,10 @@ static inline void pipe_free(int pipeno)
* Name: pipe_close
****************************************************************************/
static int pipe_close(FAR struct file *filep)
static int pipe_close(struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private;
struct Vnode *vnode = filep->f_vnode;
struct pipe_dev_s *dev = (struct pipe_dev_s *)((struct drv_data *)vnode->data)->priv;
int ret;
if (dev == NULL)
@@ -159,7 +160,7 @@ static int pipe_close(FAR struct file *filep)
/* Perform common close operations */
ret = pipecommon_close(filep);
if (ret == 0 && inode->i_crefs == 1)
if (ret == 0 && vnode->useCount <= 1)
{
/* Release the pipe when there are no further open references to it. */
@@ -174,9 +175,9 @@ static int pipe_close(FAR struct file *filep)
****************************************************************************/
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int pipe_unlink(FAR struct inode *priv)
int pipe_unlink(struct Vnode *vnode)
{
FAR struct pipe_dev_s *dev = priv->i_private;
struct pipe_dev_s *dev = ((struct drv_data *)vnode->data)->priv;
uint8_t pipeno = 0;
int ret;
@@ -185,8 +186,8 @@ static int pipe_unlink(FAR struct inode *priv)
pipeno = dev->d_pipeno;
}
/* Perform common close operations */
ret = pipecommon_unlink(priv);
if (ret == 0 && priv->i_crefs == 1)
ret = pipecommon_unlink(vnode);
if (ret == 0)
{
(void)sem_wait(&g_pipesem);
g_pipecreated &= ~(1 << pipeno);
@@ -198,7 +199,6 @@ static int pipe_unlink(FAR struct inode *priv)
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -207,7 +207,7 @@ static int pipe_unlink(FAR struct inode *priv)
* Name: pipe2
*
* Description:
* pipe() creates a pair of file descriptors, pointing to a pipe inode,
* pipe() creates a pair of file descriptors, pointing to a pipe vnode,
* and places them in the array pointed to by 'fd'. fd[0] is for reading,
* fd[1] is for writing.
*
@@ -228,11 +228,12 @@ static int pipe_unlink(FAR struct inode *priv)
int pipe(int fd[2])
{
FAR struct pipe_dev_s *dev = NULL;
struct pipe_dev_s *dev = NULL;
char devname[16];
int pipeno;
int errcode;
int ret;
struct file *filep = NULL;
size_t bufsize = 1024;
/* Get exclusive access to the pipe allocation data */
@@ -276,7 +277,7 @@ int pipe(int fd[2])
/* Register the pipe device */
ret = register_driver(devname, &pipe_fops, 0660, (FAR void *)dev);
ret = register_driver(devname, &pipe_fops, 0660, (void *)dev);
if (ret != 0)
{
(void)sem_post(&g_pipesem);
@@ -309,6 +310,12 @@ int pipe(int fd[2])
goto errout_with_wrfd;
}
ret = fs_getfilep(fd[0], &filep);
filep->ops = &pipe_fops;
ret = fs_getfilep(fd[1], &filep);
filep->ops = &pipe_fops;
return OK;
errout_with_wrfd:
Executable → Regular
+50 -52
View File
@@ -66,6 +66,8 @@
#include "user_copy.h"
#ifdef LOSCFG_KERNEL_PIPE
#include "fs/vnode.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -94,7 +96,7 @@ static void pipecommon_semtake(sem_t *sem);
* Name: pipecommon_semtake
****************************************************************************/
static void pipecommon_semtake(FAR sem_t *sem)
static void pipecommon_semtake(sem_t *sem)
{
int ret;
@@ -112,7 +114,7 @@ static void pipecommon_semtake(FAR sem_t *sem)
* Name: pipecommon_pollnotify
****************************************************************************/
static void pipecommon_pollnotify(FAR struct pipe_dev_s *dev,
static void pipecommon_pollnotify(struct pipe_dev_s *dev,
pollevent_t eventset)
{
if (eventset & POLLERR)
@@ -131,9 +133,9 @@ static void pipecommon_pollnotify(FAR struct pipe_dev_s *dev,
* Name: pipecommon_allocdev
****************************************************************************/
FAR struct pipe_dev_s *pipecommon_allocdev(size_t bufsize, const char *name)
struct pipe_dev_s *pipecommon_allocdev(size_t bufsize, const char *name)
{
FAR struct pipe_dev_s *dev;
struct pipe_dev_s *dev = NULL;
int ret;
if (bufsize > CONFIG_DEV_PIPE_MAXSIZE)
@@ -143,7 +145,7 @@ FAR struct pipe_dev_s *pipecommon_allocdev(size_t bufsize, const char *name)
/* Allocate a private structure to manage the pipe */
dev = (FAR struct pipe_dev_s *)malloc(sizeof(struct pipe_dev_s));
dev = (struct pipe_dev_s *)malloc(sizeof(struct pipe_dev_s));
if (dev)
{
/* Initialize the private structure */
@@ -173,7 +175,7 @@ FAR struct pipe_dev_s *pipecommon_allocdev(size_t bufsize, const char *name)
* Name: pipecommon_freedev
****************************************************************************/
void pipecommon_freedev(FAR struct pipe_dev_s *dev)
void pipecommon_freedev(struct pipe_dev_s *dev)
{
sem_destroy(&dev->d_bfsem);
sem_destroy(&dev->d_rdsem);
@@ -185,10 +187,10 @@ void pipecommon_freedev(FAR struct pipe_dev_s *dev)
* Name: pipecommon_open
****************************************************************************/
int pipecommon_open(FAR struct file *filep)
int pipecommon_open(struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private;
struct Vnode *vnode = filep->f_vnode;
struct pipe_dev_s *dev = (struct pipe_dev_s *)((struct drv_data *)vnode->data)->priv;
int sval;
int ret;
@@ -213,9 +215,9 @@ int pipecommon_open(FAR struct file *filep)
* is first opened.
*/
if (inode->i_crefs == 1 && dev->d_buffer == NULL)
if (vnode->useCount == 1 && dev->d_buffer == NULL)
{
dev->d_buffer = (FAR uint8_t *)malloc(dev->d_bufsize);
dev->d_buffer = (uint8_t *)malloc(dev->d_bufsize);
if (!dev->d_buffer)
{
(void)sem_post(&dev->d_bfsem);
@@ -285,6 +287,8 @@ int pipecommon_open(FAR struct file *filep)
}
}
vnode->useCount++;
return ret;
}
@@ -292,13 +296,13 @@ int pipecommon_open(FAR struct file *filep)
* Name: pipecommon_close
****************************************************************************/
int pipecommon_close(FAR struct file *filep)
int pipecommon_close(struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private;
struct Vnode *vnode = filep->f_vnode;
struct pipe_dev_s *dev = (struct pipe_dev_s *)((struct drv_data *)vnode->data)->priv;
int sval;
if (dev == NULL || filep->f_inode->i_crefs <= 0)
if (dev == NULL || filep->f_vnode->useCount <= 1)
{
return -EINVAL;
}
@@ -314,9 +318,9 @@ int pipecommon_close(FAR struct file *filep)
* still outstanding references to the pipe.
*/
/* Check if the decremented inode reference count would go to zero */
/* Check if the decremented vnode reference count would go to zero */
if (inode->i_crefs > 1)
if (vnode->useCount > 1)
{
/* More references.. If opened for writing, decrement the count of
* writers on the pipe instance.
@@ -380,6 +384,8 @@ int pipecommon_close(FAR struct file *filep)
dev->d_nreaders = 0;
}
vnode->useCount--;
sem_post(&dev->d_bfsem);
return OK;
}
@@ -388,11 +394,11 @@ int pipecommon_close(FAR struct file *filep)
* Name: pipecommon_read
****************************************************************************/
ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len)
ssize_t pipecommon_read(struct file *filep, char *buffer, size_t len)
{
FAR struct inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private;
ssize_t nread = 0;
struct Vnode *vnode = filep->f_vnode;
struct pipe_dev_s *dev = (struct pipe_dev_s *)((struct drv_data *)vnode->data)->priv;
ssize_t nread;
int sval;
int ret;
volatile int num;
@@ -548,11 +554,11 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len)
* Name: pipecommon_write
****************************************************************************/
ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer,
ssize_t pipecommon_write(struct file *filep, const char *buffer,
size_t len)
{
FAR struct inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private;
struct Vnode *vnode = filep->f_vnode;
struct pipe_dev_s *dev = (struct pipe_dev_s *)((struct drv_data *)vnode->data)->priv;
ssize_t nwritten = 0;
ssize_t last;
int nxtwrndx;
@@ -710,13 +716,13 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer,
* Name: pipecommon_poll
****************************************************************************/
int pipecommon_poll(FAR struct file *filep, poll_table *table)
int pipecommon_poll(struct file *filep, poll_table *table)
{
FAR struct inode *inode = filep->f_inode;
FAR struct pipe_dev_s *dev = inode->i_private;
struct Vnode *vnode = filep->f_vnode;
struct pipe_dev_s *dev = (struct pipe_dev_s *)((struct drv_data *)vnode->data)->priv;
pollevent_t eventset;
pipe_ndx_t nbytes;
int ret = OK;
int ret;
if (dev == NULL || table == NULL)
{
@@ -787,7 +793,7 @@ int pipecommon_poll(FAR struct file *filep, poll_table *table)
* Name: pipecommon_ioctl
****************************************************************************/
int pipecommon_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
int pipecommon_ioctl(struct file *filep, int cmd, unsigned long arg)
{
return -ENOSYS;
}
@@ -797,38 +803,30 @@ int pipecommon_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
****************************************************************************/
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
int pipecommon_unlink(FAR struct inode *inode)
int pipecommon_unlink(struct Vnode *vnode)
{
FAR struct pipe_dev_s *dev;
struct pipe_dev_s *dev = NULL;
if (inode == NULL || inode->i_private == NULL)
if (vnode == NULL || vnode->data == NULL)
{
return -EINVAL;
}
dev = ((struct drv_data *)vnode->data)->priv;
if (dev == NULL)
{
return -EINVAL;
}
dev = (FAR struct pipe_dev_s *)inode->i_private;
/* Are the any open references to the driver? */
if (inode->i_crefs == 1)
if (dev->d_buffer)
{
/* No.. free the buffer (if there is one) */
if (dev->d_buffer)
{
free(dev->d_buffer);
}
/* And free the device structure. */
unregister_driver(dev->name);
pipecommon_freedev(dev);
}
else
{
PRINTK("Device busy!\n");
return -EBUSY;
free(dev->d_buffer);
}
/* And free the device structure. */
unregister_driver(dev->name);
pipecommon_freedev(dev);
return OK;
}
#endif
+1 -1
View File
@@ -161,7 +161,7 @@ ssize_t pipecommon_write(FAR struct file *, FAR const char *, size_t);
int pipecommon_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
int pipecommon_poll(FAR struct file *filep, poll_table *fds);
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
int pipecommon_unlink(FAR struct inode *priv);
int pipecommon_unlink(struct Vnode *vnode);
#endif
int pipe_init(void);
Executable → Regular
+39 -53
View File
@@ -61,8 +61,8 @@
struct fb_chardev_s
{
FAR struct fb_vtable_s *vtable; /* Framebuffer interface */
FAR void *fbmem; /* Start of frame buffer memory */
struct fb_vtable_s *vtable; /* Framebuffer interface */
void *fbmem; /* Start of frame buffer memory */
size_t fblen; /* Size of the framebuffer */
uint8_t plane; /* Video plan number */
uint8_t bpp; /* Bits per pixel */
@@ -75,15 +75,13 @@ static struct fb_chardev_s *g_fb_dev[FB_DEV_MAXNUM] = {NULL};
* Private Function Prototypes
****************************************************************************/
static int fb_open(FAR struct file *filep);
static int fb_close(FAR struct file *filep);
static ssize_t fb_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static off_t fb_seek(FAR struct file *filep, off_t offset, int whence);
static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
static ssize_t fb_mmap(FAR struct file* filep, FAR LosVmMapRegion *region);
static int fb_open(struct file *filep);
static int fb_close(struct file *filep);
static ssize_t fb_read(struct file *filep, char *buffer, size_t buflen);
static ssize_t fb_write(struct file *filep, const char *buffer, size_t buflen);
static off_t fb_seek(struct file *filep, off_t offset, int whence);
static int fb_ioctl(struct file *filep, int cmd, unsigned long arg);
static ssize_t fb_mmap(struct file* filep, LosVmMapRegion *region);
/****************************************************************************
* Private Data
@@ -110,13 +108,13 @@ static const struct file_operations_vfs fb_fops =
* Private Functions
****************************************************************************/
static ssize_t fb_mmap(FAR struct file *filep, FAR LosVmMapRegion *region)
static ssize_t fb_mmap(struct file *filep, LosVmMapRegion *region)
{
int ret = -EINVAL;
struct fb_chardev_s *fb;
struct fb_vtable_s *vtable;
fb = (struct fb_chardev_s *)filep->f_inode->i_private;
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
if (fb == NULL)
{
return -ENODEV;
@@ -144,14 +142,14 @@ static ssize_t fb_mmap(FAR struct file *filep, FAR LosVmMapRegion *region)
*
****************************************************************************/
static int fb_open(FAR struct file *filep)
static int fb_open(struct file *filep)
{
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
DEBUGASSERT(filep != NULL && filep->f_vnode != NULL);
struct fb_chardev_s *fb;
struct fb_vtable_s *vtable;
int ret = -EINVAL;
fb = (struct fb_chardev_s *)filep->f_inode->i_private;
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
if (fb == NULL)
{
return -ENODEV;
@@ -179,14 +177,14 @@ static int fb_open(FAR struct file *filep)
*
****************************************************************************/
static int fb_close(FAR struct file *filep)
static int fb_close(struct file *filep)
{
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
DEBUGASSERT(filep != NULL && filep->f_vnode != NULL);
struct fb_chardev_s *fb;
struct fb_vtable_s *vtable;
int ret = -EINVAL;
fb = (struct fb_chardev_s *)filep->f_inode->i_private;
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
if (fb == NULL)
{
return -ENODEV;
@@ -210,10 +208,9 @@ static int fb_close(FAR struct file *filep)
* Name: fb_read
****************************************************************************/
static ssize_t fb_read(FAR struct file *filep, FAR char *buffer, size_t len)
static ssize_t fb_read(struct file *filep, char *buffer, size_t len)
{
FAR struct inode *inode;
FAR struct fb_chardev_s *fb;
struct fb_chardev_s *fb = NULL;
size_t start;
size_t end;
size_t size;
@@ -221,10 +218,8 @@ static ssize_t fb_read(FAR struct file *filep, FAR char *buffer, size_t len)
/* Get the framebuffer instance */
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
fb = (FAR struct fb_chardev_s *)inode->i_private;
DEBUGASSERT(filep != NULL && filep->f_vnode != NULL);
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
/* Get the start and size of the transfer */
start = filep->f_pos;
@@ -256,11 +251,10 @@ static ssize_t fb_read(FAR struct file *filep, FAR char *buffer, size_t len)
* Name: fb_write
****************************************************************************/
static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
static ssize_t fb_write(struct file *filep, const char *buffer,
size_t len)
{
FAR struct inode *inode;
FAR struct fb_chardev_s *fb;
struct fb_chardev_s *fb = NULL;
size_t start;
size_t end;
size_t size;
@@ -268,10 +262,8 @@ static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
/* Get the framebuffer instance */
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
fb = (FAR struct fb_chardev_s *)inode->i_private;
DEBUGASSERT(filep != NULL && filep->f_vnode != NULL);
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
/* Get the start and size of the transfer */
start = filep->f_pos;
@@ -309,19 +301,16 @@ static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
*
****************************************************************************/
static off_t fb_seek(FAR struct file *filep, off_t offset, int whence)
static off_t fb_seek(struct file *filep, off_t offset, int whence)
{
FAR struct inode *inode;
FAR struct fb_chardev_s *fb;
struct fb_chardev_s *fb = NULL;
off_t newpos;
int ret;
/* Get the framebuffer instance */
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
fb = (FAR struct fb_chardev_s *)inode->i_private;
DEBUGASSERT(filep != NULL && filep->f_vnode != NULL);
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
/* Determine the new, requested file position */
switch (whence)
@@ -378,25 +367,22 @@ static off_t fb_seek(FAR struct file *filep, off_t offset, int whence)
*
****************************************************************************/
static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
static int fb_ioctl(struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode;
FAR struct fb_chardev_s *fb;
struct fb_chardev_s *fb = NULL;
int ret;
/* Get the framebuffer instance */
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
fb = (FAR struct fb_chardev_s *)inode->i_private;
DEBUGASSERT(filep != NULL && filep->f_vnode != NULL);
fb = (struct fb_chardev_s *)((struct drv_data *)filep->f_vnode->data)->priv;
/* Process the IOCTL command */
switch (cmd)
{
case FIOC_MMAP: /* Get color plane info */
{
FAR void **ppv = (FAR void **)((uintptr_t)arg);
void **ppv = (void **)((uintptr_t)arg);
uintptr_t fbmem = (uintptr_t)fb->fbmem;
/* Return the address corresponding to the start of frame buffer. */
@@ -532,7 +518,7 @@ static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
ret = fb->vtable->getplaneinfo(fb->vtable, fb->plane, &pinfo);
if (ret >= 0)
{
nx_notify_rectangle((FAR NX_PLANEINFOTYPE *)&pinfo, &rect);
nx_notify_rectangle((NX_PLANEINFOTYPE *)&pinfo, &rect);
}
}
break;
@@ -739,7 +725,7 @@ static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
int fb_register(int display, int plane)
{
FAR struct fb_chardev_s *fb;
struct fb_chardev_s *fb = NULL;
struct fb_videoinfo_s vinfo;
struct fb_planeinfo_s pinfo;
#ifdef CONFIG_FB_OVERLAY
@@ -754,7 +740,7 @@ int fb_register(int display, int plane)
/* Allocate a framebuffer state instance */
fb = (FAR struct fb_chardev_s *)malloc(sizeof(struct fb_chardev_s));
fb = (struct fb_chardev_s *)malloc(sizeof(struct fb_chardev_s));
if (fb == NULL)
{
return -ENOMEM;
@@ -837,7 +823,7 @@ int fb_register(int display, int plane)
(void)snprintf(devname, 16, "/dev/fb%d.%d", display, plane);
}
ret = register_driver(devname, &fb_fops, 0666, (FAR void *)fb);
ret = register_driver(devname, &fb_fops, 0666, (void *)fb);
if (ret < 0)
{
gerr("ERROR: register_driver() failed: %d\n", ret);
@@ -855,7 +841,7 @@ errout_with_fb:
int fb_unregister(int display)
{
FAR struct fb_chardev_s *fb;
struct fb_chardev_s *fb = NULL;
if (display < 0 || display >= FB_DEV_MAXNUM)
return -EINVAL;
Executable → Regular
+19 -60
View File
@@ -38,19 +38,12 @@
****************************************************************************/
#include "vfs_config.h"
#include "dirent.h"
#include "errno.h"
#include "stdlib.h"
#include "fs/fs.h"
#include "fs/dirent_fs.h"
#include "inode/inode.h"
/****************************************************************************
* Private Functions
****************************************************************************/
#include "fs/vnode.h"
/****************************************************************************
* Public Functions
@@ -73,90 +66,56 @@
*
****************************************************************************/
int closedir(FAR DIR *dirp)
int closedir(DIR *dirp)
{
struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct inode *inode;
#endif
struct Vnode *vnode = NULL;
int ret;
/* Verify that we were provided with a valid directory structure */
if (!idir || idir->fd_status != DIRENT_MAGIC)
{
ret = EBADF;
ret = -EBADF;
goto errout;
}
/* A special case is when we enumerate an "empty", unused inode. That is
* an inode in the pseudo-filesystem that has no operations and no children.
* This is a "dangling" directory entry that has lost its childre.
*/
if (idir->fd_root)
{
/* This is the 'root' inode of the directory. This means different
/* This is the 'root' vnode of the directory. This means different
* things wih different filesystems.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
inode = idir->fd_root;
/* The way that we handle the close operation depends on what kind of
* root inode we have open.
*/
if (INODE_IS_MOUNTPT(inode) && !DIRENT_ISPSEUDONODE(idir->fd_flags))
vnode = idir->fd_root;
/* Perform the closedir() operation */
if (vnode->vop && vnode->vop->Closedir)
{
/* The node is a file system mointpoint. Verify that the
* mountpoint supports the closedir() method (not an error if it
* does not)
*/
if (inode->u.i_mops && inode->u.i_mops->closedir)
ret = vnode->vop->Closedir(vnode, idir);
if (ret < 0)
{
/* Perform the closedir() operation */
ret = inode->u.i_mops->closedir(inode, idir);
if (ret < 0)
{
ret = -ret;
goto errout_with_inode;
}
goto errout_with_vnode;
}
}
else
#endif
{
/* The node is part of the root pseudo file system, release
* our contained reference to the 'next' inode.
*/
if (idir->u.pseudo.fd_next)
{
inode_release(idir->u.pseudo.fd_next);
}
ret = -ENOSYS;
goto errout_with_vnode;
}
/* Release our references on the contained 'root' inode */
inode_release(idir->fd_root);
VnodeHold();
vnode->useCount--;
VnodeDrop();
}
/* Then release the container */
idir->fd_status = 0;
free(idir);
return OK;
#ifndef CONFIG_DISABLE_MOUNTPOINT
errout_with_inode:
inode_release(inode);
errout_with_vnode:
free(idir);
#endif
errout:
set_errno(ret);
set_errno(-ret);
return VFS_ERROR;
}
Executable → Regular
+102 -365
View File
@@ -39,153 +39,15 @@
****************************************************************************/
#include "vfs_config.h"
#include "dirent.h"
#include "string.h"
#include "assert.h"
#include "errno.h"
#include "stdlib.h"
#include "fs/fs.h"
#include "fs/dirent_fs.h"
#include "inode/inode.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: open_mountpoint
*
* Description:
* Handle the case where the inode to be opened is within a mountpoint.
*
* Input Parameters:
* inode -- the inode of the mountpoint to open
* relpath -- the relative path within the mountpoint to open
* dir -- the dirent structure to be initialized
*
* Returned Value:
* On success, OK is returned; Otherwise, a positive errno is returned.
*
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static inline int open_mountpoint(FAR struct inode *inode,
FAR const char *relpath,
FAR struct fs_dirent_s *dir)
{
int ret;
/* The inode itself as the 'root' of mounted volume. The actually
* directory is at relpath into the* mounted filesystem.
*
* Verify that the mountpoint inode supports the opendir() method
*/
if (!inode->u.i_mops || !inode->u.i_mops->opendir)
{
return ENOSYS;
}
/* Take reference to the mountpoint inode. Note that we do not use
* inode_addref() because we already hold the tree semaphore.
*/
inode->i_crefs++;
/* Perform the opendir() operation */
ret = inode->u.i_mops->opendir(inode, relpath, dir);
if (ret < 0)
{
/* We now need to back off our reference to the inode. We can't
* call inode_release() to do that unless we release the tree
* semaphore. The following should be safe because: (1) after the
* reference count was incremented above it should be >=1 so it should
* not decrement below zero, and (2) we hold the tree semaphore so no
* other thread should be able to change the reference count.
*/
inode->i_crefs--;
DEBUGASSERT(inode->i_crefs >= 0);
/* Negate the error value so that it can be used to set errno */
return -ret;
}
return OK;
}
#endif
/****************************************************************************
* Name: open_pseudodir
*
* Description:
* Handle the case where the inode to be opened is within the top-level
* pseudo-file system.
*
* Input Parameters:
* inode -- the inode of the mountpoint to open
* dir -- the dirent structure to be initialized
*
* Returned Value:
* None
*
****************************************************************************/
static void open_pseudodir(FAR struct inode *inode, FAR struct fs_dirent_s *dir)
{
/* We have a valid pseudo-filesystem node. Take two references on the
* inode -- one for the parent (fd_root) and one for the child (fd_next).
* Note that we do not call inode_addref because we are holding the tree
* semaphore and that would result in deadlock.
*/
inode->i_crefs++;
inode->i_child->i_crefs++;
dir->fd_root = inode; /* Save the inode where we start */
dir->u.pseudo.fd_next = inode->i_child; /* This is the next node to use for readdir() */
/* Flag the inode as belonging to the pseudo-filesystem */
#ifndef CONFIG_DISABLE_MOUNTPOINT
DIRENT_SETPSEUDONODE(dir->fd_flags);
#endif
}
/****************************************************************************
* Name: open_emptydir
*
* Description:
* Handle the case where the inode to be opened is an empty, directory node
* within the top-level pseudo-file system. That is, it has no operations
* and, therefore, it must be a directory node. But is has no children
* to be enumerated either.
*
* Input Parameters:
* dir -- the dirent structure to be initialized
*
* Returned Value:
* None
*
****************************************************************************/
static inline void open_emptydir(FAR struct fs_dirent_s *dir)
{
/* We have a valid, but empty pseudo-filesystem node. fd_next is NULL
* meaning that we are already at the end of the list of its children.
* fd_root is NULL so that if the directory is rewound, it will still be
* at the end of the list.
*/
/* Flag the inode as belonging to the pseudo-filesystem */
#ifndef CONFIG_DISABLE_MOUNTPOINT
DIRENT_SETPSEUDONODE(dir->fd_flags);
#endif
}
#include "fs/vnode.h"
#include "fs/path_cache.h"
/****************************************************************************
* Public Functions
@@ -217,141 +79,72 @@ static inline void open_emptydir(FAR struct fs_dirent_s *dir)
*
****************************************************************************/
FAR DIR *opendir(FAR const char *path)
DIR *opendir(const char *path)
{
FAR struct inode *inode;
FAR struct fs_dirent_s *dir;
FAR const char *relpath;
struct Vnode *vp = NULL;
struct fs_dirent_s *dir = NULL;
int ret;
char *fullpath;
char *fullpath_bak;
/* If we are given 'nothing' then we will interpret this as
* request for the root inode.
*/
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
if (ret < 0)
{
ret = -ret;
goto errout;
}
fullpath_bak = fullpath;
inode_semtake();
/* We don't know what to do with relative pathes */
if (*fullpath != '/')
{
ret = ENOTDIR;
goto errout_with_semaphore;
}
/* Find the node matching the path. */
inode = inode_search((FAR const char **)&fullpath, (FAR struct inode**)NULL,
(FAR struct inode**)NULL, &relpath);
/* Did we get an inode? */
if (inode == NULL)
VnodeHold();
ret = VnodeLookup(path, &vp, 0);
if (vp == NULL || ret != OK)
{
/* 'path' does not exist. */
ret = ENOTDIR;
goto errout_with_semaphore;
VnodeDrop();
goto errout;
}
if (vp->type != VNODE_TYPE_DIR)
{
ret = -ENOTDIR;
PRINT_ERR("opendir (%s) failed, err=%d\n", path, ret);
VnodeDrop();
goto errout;
}
/* Allocate a type DIR -- which is little more than an inode
* container.
*/
vp->useCount++;
VnodeDrop();
dir = (FAR struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s));
/* Allocate a type DIR -- which is little more than an vp container. */
dir = (struct fs_dirent_s *)calloc(1, sizeof(struct fs_dirent_s));
if (!dir)
{
/* Insufficient memory to complete the operation. */
ret = ENOMEM;
goto errout_with_semaphore;
ret = -ENOMEM;
goto errout_with_count;
}
/* Populate the DIR structure and return it to the caller. The way that
* we do this depends on whenever this is a "normal" pseudo-file-system
* inode or a file system mountpoint.
* vp or a file system mountpoint.
*/
dir->fd_position = 0; /* This is the position in the read stream */
/* 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
* of nodes under the directory.
*/
FAR struct inode *child = inode->i_child;
if (!*relpath && child)
if (vp->vop != NULL && vp->vop->Opendir != NULL)
{
/* It looks we have a valid pseudo-filesystem directory node. */
open_pseudodir(inode, dir);
}
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode))
{
/* Yes, the node is a file system mountpoint */
dir->fd_root = inode; /* Save the inode where we start */
/* Open the directory at the relative path */
ret = open_mountpoint(inode, relpath, dir);
if (ret != OK)
{
goto errout_with_direntry;
}
ret = vp->vop->Opendir(vp, dir);
}
else
#endif
if (!*relpath && child == NULL)
{
if (inode->u.i_ops == NULL)
{
/* This is a dangling node with no children and no operations. Set
* up to enumerate an empty directory.
*/
open_emptydir(dir);
}
else
{
ret = ENOTDIR;
goto errout_with_direntry;
}
ret = -ENOSYS;
}
else if (*relpath)
if (ret < 0)
{
ret = ENOENT;
goto errout_with_direntry;
goto errout;
}
dir->fd_status = DIRENT_MAGIC;
inode_semgive();
free(fullpath_bak);
dir->fd_root = vp;
return ((DIR *)dir);
/* Nasty goto's make error handling simpler */
errout_with_direntry:
free(dir);
errout_with_semaphore:
inode_semgive();
free(fullpath_bak);
errout_with_count:
VnodeHold();
vp->useCount--;
VnodeDrop();
errout:
set_errno(ret);
set_errno(-ret);
return NULL;
}
@@ -359,170 +152,114 @@ int do_opendir(const char *path, int oflags)
{
int ret;
int fd;
FAR struct inode *inode = NULL;
FAR struct fs_dirent_s *dir = NULL;
FAR const char *relpath = NULL;
struct Vnode *vp = NULL;
struct file *filep = NULL;
struct fs_dirent_s *dir = NULL;
char *fullpath = NULL;
FAR struct file *filep = NULL;
FAR struct inode *child = NULL;
struct inode_search_s desc;
char *relativepath = NULL;
/* If we are given 'nothing' then we will interpret this as
* request for the root inode.
*/
if (path == NULL || *path == 0)
{
ret = -EINVAL;
goto errout;
}
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
ret = get_path_from_fd(AT_FDCWD, &relativepath);
if (ret < 0)
{
ret = -ret;
goto errout;
}
/* We don't know what to do with relative pathes */
if (*fullpath != '/')
ret = vfs_normalize_path((const char *)relativepath, path, &fullpath);
if (relativepath)
{
ret = ENOTDIR;
goto errout_with_path;
free(relativepath);
}
/* Get an inode for this file */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
{
PRINTK("ERROR: Failed to find %s\n", fullpath);
/* 'path' does not exist. */
ret = ENOTDIR;
goto errout_with_path;
goto errout;
}
inode = desc.node;
relpath = desc.relpath;
/* Associate the inode with a file structure */
VnodeHold();
/* Get an vnode for this file */
ret = VnodeLookup(path, &vp, 0);
if (ret < 0)
{
PRINT_ERR("Failed to find vnode %s\n", path);
VnodeDrop();
goto errout;
}
if (vp->type != VNODE_TYPE_DIR)
{
ret = -ENOTDIR;
PRINT_ERR("opendir (%s) failed, err=%d\n", path, ret);
VnodeDrop();
goto errout;
}
vp->useCount++;
VnodeDrop();
fd = files_allocate(inode, oflags, 0, NULL, 3); /* 3: file start fd */
/* Associate the vnode with a file structure */
fd = files_allocate(vp, oflags, 0, NULL, 3); /* 3: file start fd */
if (fd < 0)
{
ret = EMFILE;
goto errout_with_inode;
ret = -EMFILE;
goto errout_with_vnode;
}
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
ret = EPERM;
/* The errno value has already been set */
ret = -EPERM;
goto errout_with_fd;
}
/* Perform the driver open operation. NOTE that the open method may be
* called many times. The driver/mountpoint logic should handled this
* because it may also be closed that many times.
*/
filep->f_path = (char *)fullpath; /* The mem will free in close(fd); */
ret = OK;
filep->f_path = fullpath; /* The mem will free in close(fd); */
filep->f_relpath = relpath;
/* Allocate a type DIR -- which is little more than an inode
* container.
*/
dir = (FAR struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s));
if (!dir)
/* Allocate a type DIR -- which is little more than an vnode container. */
dir = (struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s));
if (dir == NULL)
{
/* Insufficient memory to complete the operation. */
ret = ENOMEM;
ret = -ENOMEM;
goto errout_with_fd;
}
/* Populate the DIR structure and return it to the caller. The way that
* we do this depends on whenever this is a "normal" pseudo-file-system
* inode or a file system mountpoint.
*/
dir->fd_position = 0; /* This is the position in the read stream */
/* 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
* of nodes under the directory.
*/
child = inode->i_child;
if (!*relpath && child)
/* Open the directory at the relative path */
if (vp->vop != NULL && vp->vop->Opendir != NULL)
{
/* It looks we have a valid pseudo-filesystem directory node. */
open_pseudodir(inode, dir);
}
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode))
{
/* Yes, the node is a file system mountpoint */
dir->fd_root = inode; /* Save the inode where we start */
/* Open the directory at the relative path */
ret = open_mountpoint(inode, relpath, dir);
if (ret != OK)
{
goto errout_with_direntry;
}
ret = vp->vop->Opendir(vp, dir);
}
else
#endif
if (!*relpath && child == NULL)
{
if (inode->u.i_ops == NULL)
{
/* This is a dangling node with no children and no operations. Set
* up to enumerate an empty directory.
*/
open_emptydir(dir);
}
else
{
ret = ENOTDIR;
goto errout_with_direntry;
}
}
else if (*relpath)
{
ret = ENOENT;
goto errout_with_direntry;
ret = -ENOSYS;
}
if (ret < 0)
{
free(dir);
goto errout_with_fd;
}
dir->fd_root = vp;
dir->fd_status = DIRENT_MAGIC;
filep->f_dir = (struct fs_dirent_s *)dir;
filep->f_dir = dir;
return fd;
/* Nasty goto's make error handling simpler */
errout_with_direntry:
free(dir);
errout_with_fd:
files_release(fd);
errout_with_inode:
inode_release(inode);
errout_with_path:
free(fullpath);
errout_with_vnode:
VnodeHold();
vp->useCount--;
VnodeDrop();
errout:
set_errno(ret);
return -1;
if (fullpath)
{
free(fullpath);
}
set_errno(-ret);
return VFS_ERROR;
}
Executable → Regular
+47 -221
View File
@@ -39,151 +39,14 @@
****************************************************************************/
#include "vfs_config.h"
#include "string.h"
#include "dirent.h"
#include "errno.h"
#include "unistd.h"
#include "fs/fs.h"
#include "fs/dirent_fs.h"
#include "inode/inode.h"
#include "sys/statfs.h"
#include "user_copy.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: readpseudodir
****************************************************************************/
static inline int readpseudodir(struct fs_dirent_s *idir)
{
FAR struct inode *prev;
int ret;
/* Check if we are at the end of the list */
if (!idir->u.pseudo.fd_next)
{
/* End of file and error conditions are not distinguishable with
* readdir. Here we return -ENOENT to signal the end of the
* directory.
*/
return -ENOENT;
}
/* Copy the inode name into the dirent structure */
ret = strncpy_s(idir->fd_dir[0].d_name, NAME_MAX + 1, idir->u.pseudo.fd_next->i_name, NAME_MAX);
if (ret != EOK)
{
return -ENAMETOOLONG;
}
/* If the node has file operations, we will say that it is a file. */
idir->fd_dir[0].d_type = 0;
if (idir->u.pseudo.fd_next->u.i_ops)
{
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_BLOCK(idir->u.pseudo.fd_next))
{
idir->fd_dir[0].d_type |= DT_BLK;
}
if (INODE_IS_MOUNTPT(idir->u.pseudo.fd_next))
{
idir->fd_dir[0].d_type |= DT_DIR;
}
else
#endif
{
idir->fd_dir[0].d_type |= DT_CHR;
}
}
/* If the node has child node(s) or no operations, then we will say that
* it is a directory rather than a special file. NOTE: that the node can
* be both!
*/
if (idir->u.pseudo.fd_next->i_child || !idir->u.pseudo.fd_next->u.i_ops)
{
idir->fd_dir[0].d_type |= DT_DIR;
}
/* Now get the inode to vist next time that readdir() is called */
inode_semtake();
prev = idir->u.pseudo.fd_next;
idir->u.pseudo.fd_next = prev->i_peer; /* The next node to visit */
if (idir->u.pseudo.fd_next)
{
/* Increment the reference count on this next node */
idir->u.pseudo.fd_next->i_crefs++;
}
inode_semgive();
if (prev)
{
inode_release(prev);
}
return OK;
}
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: handlezpfsdir
* Description:
* The handlezpfsdir() function handle with the inode with zpfs magic
*
* Input Parameters:
* idir -- the pointer of one dir
*
* Returned Value:
* none
****************************************************************************/
#ifdef LOSCFG_FS_ZPFS
static inline void handlezpfsdir(struct fs_dirent_s *idir)
{
struct statfs buf;
int ret;
/* Maybe there are two or more zpfs nodes together, so we need one loop */
do
{
if (!idir->u.pseudo.fd_next || !INODE_IS_MOUNTPT(idir->u.pseudo.fd_next) ||
!idir->u.pseudo.fd_next->u.i_mops || !idir->u.pseudo.fd_next->u.i_mops->statfs)
{
return;
}
ret = idir->u.pseudo.fd_next->u.i_mops->statfs(idir->u.pseudo.fd_next, &buf);
if (ret != OK || buf.f_type != ZPFS_MAGIC)
{
return;
}
if (readpseudodir(idir) == OK)
{
idir->fd_position++;
}
} while (1);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: do_readdir
*
@@ -206,96 +69,63 @@ static inline void handlezpfsdir(struct fs_dirent_s *idir)
****************************************************************************/
static struct dirent *__readdir(DIR *dirp, int *lencnt)
{
FAR struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
struct inode *inode_ptr = NULL;
struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
struct Vnode *vnode_ptr = NULL;
int ret = 0;
int file_cnt = 0;
/* Verify that we were provided with a valid directory structure */
if (!idir || idir->fd_status != DIRENT_MAGIC)
if (!idir)
{
ret = EBADF;
ret = -EBADF;
goto errout;
}
/* A special case is when we enumerate an "empty", unused inode. That is
* an inode in the pseudo-filesystem that has no operations and no children.
* This is a "dangling" directory entry that has lost its children.
*/
inode_ptr = idir->fd_root;
if (inode_ptr == NULL)
vnode_ptr = idir->fd_root;
if (vnode_ptr == NULL)
{
/* End of file and error conditions are not distinguishable
* with readdir. We return NULL to signal either case.
*/
ret = ENOENT;
ret = -ENOENT;
goto errout;
}
/* The way we handle the readdir depends on the type of inode
* that we are dealing with.
*/
if (DIRENT_ISPSEUDONODE(idir->fd_flags))
{
#ifdef LOSCFG_FS_ZPFS
/* if the current node has the zpfs magic, we continue to skip the node */
handlezpfsdir(idir);
#endif
/* The node is part of the root pseudo file system */
ret = readpseudodir(idir);
if (ret == OK)
{
idir->fd_position++;
idir->fd_dir[0].d_off = idir->fd_position;
idir->fd_dir[0].d_reclen = (uint16_t)sizeof(struct dirent);
*lencnt = sizeof(struct dirent);
return &(idir->fd_dir[0]);
}
}
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode_ptr))
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the readdir() method
*/
if (!inode_ptr->u.i_mops || !inode_ptr->u.i_mops->readdir)
{
ret = EACCES;
goto errout;
}
/* Perform the readdir() operation */
/* Perform the readdir() operation */
#ifdef LOSCFG_ENABLE_READ_BUFFER
idir->read_cnt = MAX_DIRENT_NUM;
idir->read_cnt = MAX_DIRENT_NUM;
#else
idir->read_cnt = 1;
idir->read_cnt = 1;
#endif
file_cnt = inode_ptr->u.i_mops->readdir(inode_ptr, idir);
if (file_cnt > 0)
{
*lencnt = file_cnt * sizeof(struct dirent);
return &(idir->fd_dir[0]);
}
if (vnode_ptr->vop != NULL && vnode_ptr->vop->Readdir != NULL)
{
file_cnt = vnode_ptr->vop->Readdir(vnode_ptr, idir);
}
else
{
ret = -ENOSYS;
goto errout;
}
if (file_cnt > 0)
{
*lencnt = file_cnt * sizeof(struct dirent);
return &(idir->fd_dir[0]);
}
#endif
errout:
if (ret != OK)
if (ret < 0)
{
if (ret < 0)
{
ret = -ret;
}
set_errno(ret);
}
else if (file_cnt <= 0)
{
set_errno(ENOENT);
}
return (struct dirent *)NULL;
}
@@ -323,33 +153,30 @@ errout:
* EBADF - Invalid directory stream descriptor dir
*
****************************************************************************/
FAR struct dirent *readdir(DIR *dirp)
struct dirent *readdir(DIR *dirp)
{
int ret;
int old_err = get_errno();
int lencnt = 0;
int dirent_len = 0;
struct dirent *de = NULL;
FAR struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
int dirlen;
struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
#ifdef LOSCFG_ENABLE_READ_BUFFER
dirlen = MAX_DIRENT_NUM;
#else
dirlen = 1;
#endif
if (idir->cur_pos != 0 && idir->cur_pos < dirlen && idir->cur_pos < idir->end_pos)
if (idir->cur_pos != 0 && idir->cur_pos < MAX_DIRENT_NUM && idir->cur_pos < idir->end_pos)
{
de = &(idir->fd_dir[idir->cur_pos]);
if (idir->cur_pos == dirlen)
if (idir->cur_pos == MAX_DIRENT_NUM)
{
idir->cur_pos = 0;
}
idir->cur_pos++;
return de;
} else {
de = __readdir(dirp, &lencnt);
idir->end_pos = lencnt / sizeof(struct dirent);
}
else
{
de = __readdir(dirp, &dirent_len);
idir->end_pos = dirent_len / sizeof(struct dirent);
idir->cur_pos = 1;
if (de == NULL)
@@ -372,18 +199,18 @@ FAR struct dirent *readdir(DIR *dirp)
int do_readdir(int fd, struct dirent **de, unsigned int count)
{
struct dirent *de_src = NULL;
int lencnt = 0;
int de_len = 0;
/* Did we get a valid file descriptor? */
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct file *filep = NULL;
struct file *filep = NULL;
if (de == NULL)
{
return -EINVAL;
}
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
if ((fd < 3) || (unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
{
return -EBADF;
}
@@ -401,7 +228,8 @@ int do_readdir(int fd, struct dirent **de, unsigned int count)
}
/* Then let do_readdir do all of the work */
de_src = __readdir(filep->f_dir, &lencnt);
de_src = __readdir(filep->f_dir, &de_len);
if (de_src == NULL)
{
/* Special case: ret = -ENOENT is end of file */
@@ -409,10 +237,8 @@ int do_readdir(int fd, struct dirent **de, unsigned int count)
}
*de = de_src;
lencnt = (lencnt != 0) ? lencnt : sizeof(*de_src);
return lencnt;
return de_len;
}
#endif
return 0;
return OK;
}
Executable → Regular
+13 -71
View File
@@ -38,49 +38,11 @@
****************************************************************************/
#include "vfs_config.h"
#include "dirent.h"
#include "errno.h"
#include "fs/fs.h"
#include "fs/dirent_fs.h"
#include "inode/inode.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: rewindpseudodir
****************************************************************************/
static inline void rewindpseudodir(struct fs_dirent_s *idir)
{
struct inode *prev;
inode_semtake();
/* Reset the position to the beginning */
prev = idir->u.pseudo.fd_next; /* (Save to delete later) */
idir->u.pseudo.fd_next = idir->fd_root->i_child; /* The next node to visit */
idir->fd_position = 0; /* Reset position */
/* Increment the reference count on the root=next node. We
* should now have two references on the inode.
*/
idir->fd_root->i_child->i_crefs++;
inode_semgive();
/* Then release the reference to the old next inode */
if (prev != NULL)
{
inode_release(prev);
}
}
#include "fs/vnode.h"
/****************************************************************************
* Public Functions
@@ -102,19 +64,10 @@ static inline void rewindpseudodir(struct fs_dirent_s *idir)
*
****************************************************************************/
void rewinddir(FAR DIR *dirp)
void rewinddir(DIR *dirp)
{
struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct inode *inode_ptr;
#endif
/* Verify that we were provided with a valid directory structure,
* A special case is when we enumerate an "empty", unused inode (fd_root
* == 0). That is an inode in the pseudo-filesystem that has no
* operations and no children. This is a "dangling" directory entry that
* has lost its children.
*/
struct Vnode *vnode_ptr = NULL;
if (!idir || !idir->fd_root || idir->fd_status != DIRENT_MAGIC)
{
@@ -122,34 +75,23 @@ void rewinddir(FAR DIR *dirp)
return;
}
/* The way we handle the readdir depends on the type of inode
/* The way we handle the readdir depends on the type of vnode
* that we are dealing with.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
inode_ptr = idir->fd_root;
if (INODE_IS_MOUNTPT(inode_ptr))
vnode_ptr = idir->fd_root;
if (vnode_ptr->vop != NULL && vnode_ptr->vop->Rewinddir != NULL)
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the rewinddir() method
*/
/* Perform the rewinddir() operation */
if (inode_ptr->u.i_mops && inode_ptr->u.i_mops->rewinddir)
{
/* Perform the rewinddir() operation */
(void)inode_ptr->u.i_mops->rewinddir(inode_ptr, idir);
}
/* Reset position for telldir() */
idir->fd_position = 0;
vnode_ptr->vop->Rewinddir(vnode_ptr, idir);
}
else
#endif
{
/* The node is part of the root pseudo file system */
rewindpseudodir(idir);
set_errno(ENOSYS);
}
/* Reset position for telldir() */
idir->fd_position = 0;
}
Executable → Regular
+8 -95
View File
@@ -38,85 +38,23 @@
****************************************************************************/
#include "vfs_config.h"
#include "sys/types.h"
#include "dirent.h"
#include "errno.h"
#include "fs/fs.h"
#include "fs/dirent_fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: seekpseudodir
****************************************************************************/
static inline void seekpseudodir(struct fs_dirent_s *idir, off_t offset)
{
struct inode *curr;
struct inode *prev;
off_t pos;
/* Determine a starting point for the seek. If the seek
* is "forward" from the current position, then we will
* start at the current poisition. Otherwise, we will
* "rewind" to the root dir.
*/
if (offset < idir->fd_position)
{
pos = 0;
curr = idir->fd_root->i_child;
}
else
{
pos = idir->fd_position;
curr = idir->u.pseudo.fd_next;
}
/* Traverse the peer list starting at the 'root' of the
* the list until we find the node at 'offset". If devices
* are being registered and unregistered, then this can
* be a very unpredictable operation.
*/
inode_semtake();
for (; curr && pos != offset; pos++, curr = curr->i_peer);
/* Now get the inode to vist next time that readdir() is called */
prev = idir->u.pseudo.fd_next;
idir->u.pseudo.fd_next = curr; /* The next node to visit (might be null) */
idir->fd_position = pos; /* Might be beyond the last dirent */
if (curr)
{
/* Increment the reference count on this next node */
curr->i_crefs++;
}
inode_semgive();
if (prev)
{
inode_release(prev);
}
}
/****************************************************************************
* Name: seekmountptdir
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset)
{
struct inode *inode;
struct Vnode *vnode;
off_t pos;
/* Determine a starting point for the seek. If the seek
@@ -125,14 +63,14 @@ static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset)
* "rewind" to the root dir.
*/
inode = idir->fd_root;
vnode = idir->fd_root;
if (offset < idir->fd_position)
{
if (inode->u.i_mops && inode->u.i_mops->rewinddir)
if (vnode->vop != NULL && vnode->vop->Rewinddir != NULL)
{
/* Perform the rewinddir() operation */
inode->u.i_mops->rewinddir(inode, idir);
vnode->vop->Rewinddir(vnode, idir);
pos = 0;
}
else
@@ -157,8 +95,8 @@ static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset)
while (pos < offset)
{
if (!inode->u.i_mops || !inode->u.i_mops->readdir ||
inode->u.i_mops->readdir(inode, idir) <= 0)
if (!vnode->vop || !vnode->vop->Readdir ||
vnode->vop->Readdir(vnode, idir) <= 0)
{
/* We can't read the next entry and there is no way to return
* an error indication.
@@ -175,7 +113,6 @@ static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset)
/* If we get here the directory position has been successfully set */
idir->fd_position = pos;
}
#endif
/****************************************************************************
* Public Functions
@@ -203,13 +140,6 @@ void seekdir(DIR *dirp, long offset)
{
struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
/* Verify that we were provided with a valid directory structure,
* A special case is when we enumerate an "empty", unused inode (fd_root
* == 0). That is an inode in the pseudo-filesystem that has no
* operations and no children. This is a "dangling" directory entry that
* has lost its children.
*/
if (!idir || !idir->fd_root || idir->fd_status != DIRENT_MAGIC)
{
set_errno(EBADF);
@@ -222,22 +152,5 @@ void seekdir(DIR *dirp, long offset)
return;
}
/* The way we handle the readdir depends on the type of inode
* that we are dealing with.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(idir->fd_root))
{
/* The node is a file system mointpoint */
seekmountptdir(idir, offset);
}
else
#endif
{
/* The node is part of the root pseudo file system */
seekpseudodir(idir, offset);
}
seekmountptdir(idir, offset);
}
Executable → Regular
-1
View File
@@ -45,7 +45,6 @@
#include "fs/fs.h"
#include "fs/dirent_fs.h"
#include "inode/inode.h"
/****************************************************************************
* Public Functions
+14 -17
View File
@@ -169,7 +169,9 @@ static char *unique_chardev(void)
int block_proxy(FAR const char *blkdev, int oflags)
{
FAR char *chardev;
struct file *filep = NULL;
struct Vnode *vnode = NULL;
char *chardev;
bool readonly;
int ret;
int fd;
@@ -211,23 +213,21 @@ int block_proxy(FAR const char *blkdev, int oflags)
goto errout_with_bchdev;
}
/* Unlink the character device name. The driver instance will persist,
* provided that CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y (otherwise, we have
* a problem here!)
*/
ret = unlink(chardev);
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
ret = -errno;
PRINTK("ERROR: Failed to unlink %s: %d\n", chardev, ret);
files_release(fd);
ret = -get_errno();
goto errout_with_bchdev;
}
ret = unregister_driver(chardev);
if (ret < 0 && ret != -EBUSY)
{
PRINTK("ERROR: Failed to unregister %s: %d\n", chardev, ret);
}
vnode = filep->f_vnode;
VnodeHold();
vnode->type = VNODE_TYPE_BCHR;
VnodeDrop();
/* Block char device is no need for file mapping */
(void)remove_mapping(chardev);
/* Free the allocate character driver name and return the open file
* descriptor.
@@ -238,10 +238,7 @@ int block_proxy(FAR const char *blkdev, int oflags)
return fd;
errout_with_bchdev:
(void)bchdev_unregister(chardev);
(void)unlink(chardev);
(void)unregister_driver(chardev);
errout_with_chardev:
(void)free(chardev);
(void)sem_destroy(&g_devno_sem);
Executable → Regular
+24 -23
View File
@@ -39,11 +39,9 @@
#include "fs/fs.h"
#include "vfs_config.h"
#include "debug.h"
#include "errno.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "disk.h"
/****************************************************************************
@@ -54,56 +52,57 @@
* Name: close_blockdriver
*
* Description:
* Call the close method and release the inode
* Call the close method and release the vnode
*
* Input Parameters:
* inode - reference to the inode of a block driver opened by open_blockdriver
* vnode - reference to the vnode of a block driver opened by open_blockdriver
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* EINVAL - inode is NULL
* ENOTBLK - The inode is not a block driver
* EINVAL - vnode is NULL
* ENOTBLK - The vnode is not a block driver
*
****************************************************************************/
int close_blockdriver(FAR struct inode *inode_ptr)
int close_blockdriver(struct Vnode *vnode_ptr)
{
#ifdef VFS_IMPL_LATER
int ret = 0; /* Assume success */
los_part *part = NULL;
los_disk *disk = NULL;
/* Sanity checks */
if (!inode_ptr || !inode_ptr->u.i_bops)
if (!vnode_ptr || !vnode_ptr->u.i_bops)
{
ret = -EINVAL;
goto errout;
}
/* Verify that the inode is a block driver. */
/* Verify that the vnode is a block driver. */
if (!INODE_IS_BLOCK(inode_ptr))
if (!INODE_IS_BLOCK(vnode_ptr))
{
fdbg("inode is not a block driver\n");
fdbg("vnode is not a block driver\n");
ret = -ENOTBLK;
goto errout;
}
part = los_part_find(inode_ptr);
part = los_part_find(vnode_ptr);
if (part != NULL)
{
disk = get_disk(part->disk_id);
if (disk == NULL)
{
ret = -EINVAL;
goto errout_with_inode;
goto errout_with_vnode;
}
if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR)
{
PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
inode_release(inode_ptr);
vnode_release(vnode_ptr);
return -1;
}
if (disk->disk_status == STAT_INUSED)
@@ -113,34 +112,36 @@ int close_blockdriver(FAR struct inode *inode_ptr)
* if needed.
*/
if (inode_ptr->u.i_bops->close != NULL)
if (vnode_ptr->u.i_bops->close != NULL)
{
ret = inode_ptr->u.i_bops->close(inode_ptr);
ret = vnode_ptr->u.i_bops->close(vnode_ptr);
}
}
if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR)
{
PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
inode_release(inode_ptr);
vnode_release(vnode_ptr);
return -1;
}
}
else
{
if ((inode_ptr->i_flags & FSNODEFLAG_DELETED) == 0 && inode_ptr->u.i_bops->close != NULL)
if ((vnode_ptr->i_flags & FSNODEFLAG_DELETED) == 0 && vnode_ptr->u.i_bops->close != NULL)
{
ret = inode_ptr->u.i_bops->close(inode_ptr);
ret = vnode_ptr->u.i_bops->close(vnode_ptr);
}
}
errout_with_inode:
errout_with_vnode:
/* Then release the reference on the inode */
/* Then release the reference on the vnode */
inode_release(inode_ptr);
vnode_release(vnode_ptr);
errout:
return ret;
#endif
return 0;
}
Executable → Regular
View File
Executable → Regular
+46 -4
View File
@@ -39,15 +39,12 @@
#include "vfs_config.h"
#include "driver/driver.h"
#include "sys/types.h"
#include "sys/mount.h"
#include "debug.h"
#include "errno.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "driver/driver.h"
#include "string.h"
/****************************************************************************
@@ -75,7 +72,51 @@
* support write access
*
****************************************************************************/
int find_blockdriver(const char *pathname, int mountflags, struct Vnode **vpp)
{
int ret;
struct Vnode *vp = NULL;
/* Sanity checks */
/* Find the vnode registered with this pathname */
VnodeHold();
ret = VnodeLookup(pathname, &vp, V_DUMMY);
if (ret < 0)
{
ret = -EACCES;
goto errout;
}
/* Verify that the vnode is a block driver. */
if (vp->type != VNODE_TYPE_BLK)
{
fdbg("%s is not a block driver\n", pathname);
ret = -ENOTBLK;
goto errout;
}
/* Make sure that the vnode supports the requested access */
struct block_operations *i_bops = (struct block_operations *)((struct drv_data *)vp->data)->ops;
if (i_bops == NULL || i_bops->read == NULL || (i_bops->write == NULL && (mountflags & MS_RDONLY) == 0))
{
fdbg("%s does not support requested access\n", pathname);
ret = -EACCES;
goto errout;
}
*vpp = vp;
VnodeDrop();
return OK;
errout:
VnodeDrop();
return ret;
}
#ifdef VFS_IMPL_LATER
int find_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode)
{
@@ -132,3 +173,4 @@ errout_with_inode:
errout:
return ret;
}
#endif
Executable → Regular
+28 -26
View File
@@ -38,14 +38,13 @@
****************************************************************************/
#include "vfs_config.h"
#include "debug.h"
#include "errno.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "driver/driver.h"
#include "disk.h"
#include <linux/kernel.h>
/****************************************************************************
* Public Functions
@@ -55,29 +54,32 @@
* Name: open_blockdriver
*
* Description:
* Return the inode of the block driver specified by 'pathname'
* Return the vnode of the block driver specified by 'pathname'
*
* Input Parameters:
* pathname - the full path to the block driver to be opened
* mountflags - if MS_RDONLY is not set, then driver must support write
* operations (see include/sys/mount.h)
* ppinode - address of the location to return the inode reference
* ppvnode - address of the location to return the vnode reference
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* EINVAL - pathname or pinode is NULL
* EINVAL - pathname or pvnode is NULL
* ENOENT - No block driver of this name is registered
* ENOTBLK - The inode associated with the pathname is not a block driver
* ENOTBLK - The vnode associated with the pathname is not a block driver
* EACCESS - The MS_RDONLY option was not set but this driver does not
* support write access
*
****************************************************************************/
int open_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode)
extern int find_blockdriver(const char *pathname, int mountflags, struct Vnode **vpp);
int open_blockdriver(const char *pathname, int mountflags,
struct Vnode **ppvnode)
{
FAR struct inode *inode_ptr = NULL;
struct Vnode *vnode_ptr = NULL;
los_part *part = NULL;
los_disk *disk = NULL;
int ret;
@@ -85,18 +87,18 @@ int open_blockdriver(FAR const char *pathname, int mountflags,
/* Minimal sanity checks */
#ifdef CONFIG_DEBUG
if (ppinode == NULL)
if (ppvnode == NULL)
{
ret = -EINVAL;
goto errout;
}
#endif
/* Find the inode associated with this block driver name. find_blockdriver
/* Find the vnode associated with this block driver name. find_blockdriver
* will perform all additional error checking.
*/
ret = find_blockdriver(pathname, mountflags, &inode_ptr);
ret = find_blockdriver(pathname, mountflags, &vnode_ptr);
if (ret < 0)
{
fdbg("Failed to file %s block driver\n", pathname);
@@ -108,33 +110,35 @@ int open_blockdriver(FAR const char *pathname, int mountflags,
* if needed.
*/
part = los_part_find(inode_ptr);
struct drv_data* drv = (struct drv_data*)vnode_ptr->data;
struct block_operations *ops = (struct block_operations *)drv->ops;
part = los_part_find(vnode_ptr);
if (part != NULL)
{
disk = get_disk(part->disk_id);
if (disk == NULL)
{
ret = -EINVAL;
goto errout_with_inode;
goto errout_with_vnode;
}
if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR)
{
PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
inode_release(inode_ptr);
return -1;
}
if (disk->disk_status == STAT_INUSED)
{
if (inode_ptr->u.i_bops->open != NULL)
if (ops->open != NULL)
{
ret = inode_ptr->u.i_bops->open(inode_ptr);
ret = ops->open(vnode_ptr);
if (ret < 0)
{
fdbg("%s driver open failed\n", pathname);
(void)pthread_mutex_unlock(&disk->disk_mutex);
goto errout_with_inode;
goto errout_with_vnode;
}
}
}
@@ -142,29 +146,27 @@ int open_blockdriver(FAR const char *pathname, int mountflags,
if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR)
{
PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
inode_release(inode_ptr);
return -1;
}
}
else
{
if ((inode_ptr->i_flags & FSNODEFLAG_DELETED) == 0 && inode_ptr->u.i_bops->open != NULL)
if (ops->open != NULL)
{
ret = inode_ptr->u.i_bops->open(inode_ptr);
ret = ops->open(vnode_ptr);
if (ret < 0)
{
fdbg("%s driver open failed\n", pathname);
goto errout_with_inode;
goto errout_with_vnode;
}
}
}
*ppinode = inode_ptr;
*ppvnode = vnode_ptr;
return OK;
errout_with_inode:
inode_release(inode_ptr);
errout_with_vnode:
errout:
return ret;
}
+32 -29
View File
@@ -38,14 +38,16 @@
****************************************************************************/
#include "vfs_config.h"
#include "sys/types.h"
#include "errno.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "string.h"
#include "fs/vfs_util.h"
#include "fs/path_cache.h"
#include "fs/vnode.h"
#include "limits.h"
#ifndef CONFIG_DISABLE_MOUNTPOINT
@@ -57,62 +59,63 @@
* Name: register_blockdriver
*
* Description:
* Register a block driver inode the pseudo file system.
* Register a block driver vnode the pseudo file system.
*
* Input parameters:
* path - The path to the inode to create
* path - The path to the vnode to create
* bops - The block driver operations structure
* mode - inmode priviledges (not used)
* priv - Private, user data that will be associated with the inode.
* priv - Private, user data that will be associated with the vnode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* Zero on success (with the vnode point in 'vnode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
* vnode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* EEXIST - An vnode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/
int register_blockdriver(FAR const char *path,
FAR const struct block_operations *bops,
mode_t mode, FAR void *priv)
int register_blockdriver(const char *path,
const struct block_operations *bops,
mode_t mode, void *priv)
{
FAR struct inode *node;
struct Vnode *vp = NULL;
int ret;
if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
{
return EINVAL;
return -EINVAL;
}
/* Insert an inode for the device driver -- we need to hold the inode
/* Insert an vnode for the device driver -- we need to hold the vnode
* semaphore to prevent access to the tree while we this. This is because
* we will have a momentarily bad true until we populate the inode with
* we will have a momentarily bad true until we populate the vnode with
* valid data.
*/
inode_semtake();
ret = inode_reserve(path, &node);
struct drv_data *data = (struct drv_data *)zalloc(sizeof(struct drv_data));
data->ops = (void *)bops;
data->mode = mode;
data->priv = priv;
VnodeHold();
ret = VnodeLookup(path, &vp, V_CREATE | V_CACHE | V_DUMMY);
if (ret >= 0)
{
/* We have it, now populate it with block driver specific information. */
INODE_SET_BLOCK(node);
node->u.i_bops = bops;
#ifdef LOSCFG_FILE_MODE
node->i_mode = mode;
#endif
node->i_private = priv;
ret = OK;
vp->type = VNODE_TYPE_BLK;
vp->data = data;
vp->mode = mode;
ret = OK;
}
inode_semgive();
VnodeDrop();
return ret;
}
#endif /* !CONFIG_DISABLE_MOUNTPOINT */
Executable → Regular
+38 -28
View File
@@ -38,14 +38,14 @@
****************************************************************************/
#include "vfs_config.h"
#include "sys/types.h"
#include "errno.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "string.h"
#include "fs/vfs_util.h"
#include "fs/path_cache.h"
#include "limits.h"
/****************************************************************************
* Public Functions
@@ -55,29 +55,29 @@
* Name: register_driver
*
* Description:
* Register a character driver inode the pseudo file system.
* Register a character driver vnode the pseudo file system.
*
* Input Parameters:
* path - The path to the inode to create
* path - The path to the vnode to create
* fops - The file operations structure
* mode - inmode priviledges (not used)
* priv - Private, user data that will be associated with the inode.
* priv - Private, user data that will be associated with the vnode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* Zero on success (with the vnode point in 'vnode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
* vnode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* EEXIST - An vnode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/
int register_driver(FAR const char *path, FAR const struct file_operations_vfs *fops,
mode_t mode, FAR void *priv)
int register_driver(const char *path, const struct file_operations_vfs *fops,
mode_t mode, void *priv)
{
FAR struct inode *node;
struct Vnode *vnode = NULL;
int ret;
if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
@@ -85,28 +85,38 @@ int register_driver(FAR const char *path, FAR const struct file_operations_vfs *
return -EINVAL;
}
/* Insert a dummy node -- we need to hold the inode semaphore because we
VnodeHold();
ret = VnodeLookup(path, &vnode, 0);
if (ret == 0)
{
VnodeDrop();
return -EEXIST;
}
/* Insert a dummy node -- we need to hold the vnode semaphore because we
* will have a momentarily bad structure.
*/
inode_semtake();
ret = inode_reserve(path, &node);
if (ret >= 0)
struct drv_data *data = (struct drv_data *)zalloc(sizeof(struct drv_data));
data->ops = (void *)fops;
data->mode = mode;
data->priv = priv;
ret = VnodeLookup(path, &vnode, V_CREATE | V_CACHE | V_DUMMY);
if (ret == OK)
{
/* We have it, now populate it with driver specific information.
* NOTE that the initial reference count on the new inode is zero.
* NOTE that the initial reference count on the new vnode is zero.
*/
INODE_SET_DRIVER(node);
node->u.i_ops = fops;
#ifdef LOSCFG_FILE_MODE
node->i_mode = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
#endif
node->i_private = priv;
ret = OK;
vnode->type = VNODE_TYPE_CHR;
vnode->data = data;
vnode->mode = mode;
vnode->fop = (struct file_operations_vfs *)fops;
ret = OK;
}
inode_semgive();
VnodeDrop();
return ret;
}
+1 -6
View File
@@ -59,15 +59,10 @@
int unregister_blockdriver(const char *path)
{
int ret;
if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
{
return EINVAL;
}
inode_semtake();
ret = inode_remove(path);
inode_semgive();
return ret;
return -ENOSYS;
}
Executable → Regular
+5 -14
View File
@@ -41,7 +41,7 @@
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "string.h"
#include "errno.h"
@@ -53,21 +53,12 @@
* Name: unregister_driver
*
* Description:
* Remove the character driver inode at 'path' from the pseudo-file system
* Remove the character driver vnode at 'path' from the pseudo-file system
*
****************************************************************************/
int unregister_driver(FAR const char *path)
int unregister_driver(const char *path)
{
int ret;
if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
{
return -EINVAL;
}
inode_semtake();
ret = inode_remove(path);
inode_semgive();
return ret;
(void)path;
return 0;
}
Executable → Regular
+109 -113
View File
@@ -39,18 +39,17 @@
****************************************************************************/
#include "unistd.h"
#include "vfs_config.h"
#include "sys/types.h"
#include "string.h"
#include "dirent.h"
#include "semaphore.h"
#include "assert.h"
#include "errno.h"
#include "fs/fs.h"
#include "fs/file.h"
#include "stdio.h"
#include "stdlib.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "los_mux.h"
#include "fs/fd_table.h"
#ifdef LOSCFG_NET_LWIP_SACK
@@ -105,6 +104,20 @@ static void clear_bit(int i, void *addr)
*addri = old;
}
bool get_bit(int i)
{
unsigned int *p = NULL;
unsigned int mask;
p = ((unsigned int *)bitmap) + (i >> 5); /* Gets the location in the bitmap */
mask = 1 << (i & 0x1f); /* Gets the mask for the current bit int bitmap */
if (!(~(*p) & mask)){
return true;
}
return false;
}
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -113,7 +126,7 @@ static void clear_bit(int i, void *addr)
* Name: _files_semtake
****************************************************************************/
static void _files_semtake(FAR struct filelist *list)
static void _files_semtake(struct filelist *list)
{
/* Take the semaphore (perhaps waiting) */
@@ -137,71 +150,72 @@ static void _files_semtake(FAR struct filelist *list)
* Name: _files_close
*
* Description:
* Close an inode (if open)
* Close an vnode (if open)
*
* Assumuptions:
* Caller holds the list semaphore because the file descriptor will be freed.
*
****************************************************************************/
static int _files_close(FAR struct file *filep)
static int _files_close(struct file *filep)
{
struct inode *inode = filep->f_inode;
struct Vnode *vnode = filep->f_vnode;
int ret = OK;
/* Check if the struct file is open (i.e., assigned an inode) */
if (inode)
/* Check if the struct file is open (i.e., assigned an vnode) */
if (filep->f_oflags & O_DIRECTORY)
{
if (filep->f_oflags & O_DIRECTORY)
ret = closedir(filep->f_dir);
if (ret != OK)
{
ret = closedir(filep->f_dir);
return ret;
}
}
else
{
/* Close the file, driver, or mountpoint. */
if (filep->ops && filep->ops->close)
{
/* Perform the close operation */
ret = filep->ops->close(filep);
if (ret != OK)
{
return ret;
}
}
else
{
/* Close the file, driver, or mountpoint. */
if (inode->u.i_ops && inode->u.i_ops->close)
{
/* Perform the close operation */
ret = inode->u.i_ops->close(filep);
if (ret != OK)
{
return ret;
}
}
}
/* Drop file caches */
(void)remove_mapping_nolock(filep->f_path, filep);
/* And release the inode */
inode_release(inode);
/* Release the path of file */
free(filep->f_path);
/* Release the file descriptor */
filep->f_magicnum = 0;
filep->f_oflags = 0;
filep->f_pos = 0;
filep->f_path = NULL;
filep->f_priv = NULL;
filep->f_inode = NULL;
filep->f_refcount = 0;
filep->f_mapping = NULL;
filep->f_dir = NULL;
VnodeHold();
vnode->useCount--;
VnodeDrop();
}
/* Block char device is removed when close */
if (vnode->type == VNODE_TYPE_BCHR)
{
VnodeHold();
ret = VnodeFree(vnode);
if (ret < 0)
{
PRINTK("Removing bchar device %s failed\n", filep->f_path);
}
VnodeDrop();
}
/* Release the path of file */
free(filep->f_path);
/* Release the file descriptor */
filep->f_magicnum = 0;
filep->f_oflags = 0;
filep->f_pos = 0;
filep->f_path = NULL;
filep->f_priv = NULL;
filep->f_vnode = NULL;
filep->f_refcount = 0;
filep->f_mapping = NULL;
filep->f_dir = NULL;
return ret;
}
@@ -228,7 +242,7 @@ void files_initialize(void)
*
****************************************************************************/
void files_initlist(FAR struct filelist *list)
void files_initlist(struct filelist *list)
{
DEBUGASSERT(list);
@@ -245,7 +259,7 @@ void files_initlist(FAR struct filelist *list)
*
****************************************************************************/
void files_releaselist(FAR struct filelist *list)
void files_releaselist(struct filelist *list)
{
int i;
@@ -270,7 +284,7 @@ void files_releaselist(FAR struct filelist *list)
* Name: file_dup2
*
* Description:
* Assign an inode to a specific files structure. This is the heart of
* Assign an vnode to a specific files structure. This is the heart of
* dup2.
*
* Equivalent to the non-standard fs_dupfd2() function except that it
@@ -283,20 +297,19 @@ void files_releaselist(FAR struct filelist *list)
*
****************************************************************************/
int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
int file_dup2(struct file *filep1, struct file *filep2)
{
FAR struct filelist *list = NULL;
FAR struct inode *inode_ptr = NULL;
struct filelist *list = NULL;
struct Vnode *vnode_ptr = NULL;
char *fullpath = NULL;
const char *relpath = NULL;
int err;
int len;
int ret;
struct inode_search_s desc;
if (!filep1 || !filep1->f_inode || !filep2)
if (!filep1 || !filep1->f_vnode || !filep2)
{
err = EBADF;
err = -EBADF;
goto errout;
}
@@ -314,8 +327,8 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
_files_semtake(list);
}
/* If there is already an inode contained in the new file structure,
* close the file and release the inode.
/* If there is already an vnode contained in the new file structure,
* close the file and release the vnode.
*/
ret = _files_close(filep2);
@@ -340,26 +353,18 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
goto errout_with_ret;
}
/* Increment the reference count on the contained inode */
/* Increment the reference count on the contained vnode */
inode_ptr = filep1->f_inode;
vnode_ptr = filep1->f_vnode;
/* Then clone the file structure */
filep2->f_oflags = filep1->f_oflags;
filep2->f_pos = filep1->f_pos;
filep2->f_inode = inode_ptr;
filep2->f_vnode = vnode_ptr;
filep2->f_priv = filep1->f_priv;
(void)strncpy_s(fullpath, len + 1, filep1->f_path, len);
SETUP_SEARCH(&desc, fullpath, false);
if (inode_find(&desc) < 0)
{
ret = -EACCES;
free(fullpath);
goto errout_with_ret;
}
relpath = desc.relpath;
filep2->f_path = fullpath;
filep2->f_relpath = relpath;
@@ -367,18 +372,14 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
* can maintain the correct open counts.
*/
if (inode_ptr->u.i_ops)
if (vnode_ptr->vop)
{
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode_ptr))
if (vnode_ptr->originMount)
{
/* Dup the open file on the in the new file structure */
if (inode_ptr->u.i_mops->dup)
{
ret = inode_ptr->u.i_mops->dup(filep1, filep2);
}
else
if (vnode_ptr == NULL)
{
ret = -ENOSYS;
}
@@ -388,9 +389,9 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
{
/* (Re-)open the pseudo file or device driver */
if (inode_ptr->u.i_ops->open)
if (vnode_ptr->vop->Open)
{
ret = inode_ptr->u.i_ops->open(filep2);
ret = vnode_ptr->vop->Open(vnode_ptr, 0, 0, 0);
}
else
{
@@ -402,7 +403,7 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
if (ret < 0)
{
goto errout_with_inode;
goto errout_with_vnode;
}
}
@@ -414,13 +415,12 @@ int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
/* Handle various error conditions */
errout_with_inode:
errout_with_vnode:
inode_release(filep2->f_inode);
free(filep2->f_path);
filep2->f_oflags = 0;
filep2->f_pos = 0;
filep2->f_inode = NULL;
filep2->f_vnode = NULL;
filep2->f_priv = NULL;
filep2->f_path = NULL;
filep2->f_relpath = NULL;
@@ -451,9 +451,9 @@ static inline unsigned int files_magic_generate(void)
*
****************************************************************************/
int files_allocate(FAR struct inode *inode_ptr, int oflags, off_t pos,void* priv, int minfd)
int files_allocate(struct Vnode *vnode_ptr, int oflags, off_t pos, void *priv, int minfd)
{
FAR struct filelist *list = NULL;
struct filelist *list = NULL;
unsigned int *p = NULL;
unsigned int mask;
unsigned int i;
@@ -481,7 +481,7 @@ int files_allocate(FAR struct inode *inode_ptr, int oflags, off_t pos,void* priv
set_bit(i, bitmap);
list->fl_files[i].f_oflags = oflags;
list->fl_files[i].f_pos = pos;
list->fl_files[i].f_inode = inode_ptr;
list->fl_files[i].f_vnode = vnode_ptr;
list->fl_files[i].f_priv = priv;
list->fl_files[i].f_refcount = 1;
list->fl_files[i].f_mapping = NULL;
@@ -500,19 +500,18 @@ int files_allocate(FAR struct inode *inode_ptr, int oflags, off_t pos,void* priv
i++;
}
_files_semgive(list);
return VFS_ERROR;
}
static int files_close_internal(int fd, LosProcessCB *processCB)
{
FAR struct filelist *list = NULL;
int ret = OK;
int ret = OK;
struct file *filep = NULL;
struct filelist *list = NULL;
struct files_struct *process_files = NULL;
/* 0,1,2 fd is not opened in system, no need to close them */
if ((fd >= STDIN_FILENO) && (fd <= STDERR_FILENO))
{
return OK;
@@ -525,9 +524,9 @@ static int files_close_internal(int fd, LosProcessCB *processCB)
list = sched_getfiles();
DEBUGASSERT(list != NULL);
/* If the file was properly opened, there should be an inode assigned */
/* If the file was properly opened, there should be an vnode assigned */
if (fd < 0 || fd >= CONFIG_NFILE_DESCRIPTORS || !list->fl_files[fd].f_inode)
if (fd < 0 || fd >= CONFIG_NFILE_DESCRIPTORS || !list->fl_files[fd].f_vnode)
{
return -EBADF;
}
@@ -542,20 +541,18 @@ static int files_close_internal(int fd, LosProcessCB *processCB)
_files_semgive(list);
return -EINVAL;
}
if (list->fl_files[fd].f_mapping)
{
OsFileCacheFlush(list->fl_files[fd].f_mapping);
dec_mapping(list->fl_files[fd].f_mapping);
}
list->fl_files[fd].f_refcount--;
/* The filep->f_refcount may not be zero here, when the filep is shared in parent-child processes.
so, upon closing the filep in current process, relevant region must be released immediately */
OsVmmFileRegionFree(&list->fl_files[fd], processCB);
filep = &list->fl_files[fd];
OsVmmFileRegionFree(filep, processCB);
list->fl_files[fd].f_refcount--;
if (list->fl_files[fd].f_refcount == 0)
{
dec_mapping_nolock(filep->f_mapping);
ret = _files_close(&list->fl_files[fd]);
if (ret == OK)
{
@@ -594,7 +591,7 @@ int files_close(int fd)
void files_release(int fd)
{
FAR struct filelist *list = NULL;
struct filelist *list = NULL;
list = sched_getfiles();
DEBUGASSERT(list);
@@ -605,7 +602,7 @@ void files_release(int fd)
list->fl_files[fd].f_magicnum = 0;
list->fl_files[fd].f_oflags = 0;
list->fl_files[fd].f_inode = NULL;
list->fl_files[fd].f_vnode = NULL;
list->fl_files[fd].f_pos = 0;
list->fl_files[fd].f_refcount = 0;
list->fl_files[fd].f_path = NULL;
@@ -613,15 +610,14 @@ void files_release(int fd)
list->fl_files[fd].f_priv = NULL;
list->fl_files[fd].f_mapping = NULL;
list->fl_files[fd].f_dir = NULL;
clear_bit(fd, bitmap);
_files_semgive(list);
}
}
struct inode * files_get_openfile(int fd)
struct Vnode *files_get_openfile(int fd)
{
FAR struct filelist *list = NULL;
struct filelist *list = NULL;
unsigned int *p = NULL;
unsigned int mask;
@@ -635,12 +631,12 @@ struct inode * files_get_openfile(int fd)
return NULL;
}
return list->fl_files[fd].f_inode;
return list->fl_files[fd].f_vnode;
}
int alloc_fd(int minfd)
{
FAR struct filelist *list = NULL;
struct filelist *list = NULL;
unsigned int *p = NULL;
unsigned int mask;
unsigned int i;
@@ -679,16 +675,16 @@ void clear_fd(int fd)
clear_bit(fd, bitmap);
}
int close_files(struct inode *inode)
int close_files(struct Vnode *vnode)
{
int fd = 0;
int ret = 0;
FAR struct inode *open_file_inode = NULL;
struct Vnode *open_file_vnode = NULL;
for (fd = FILE_START_FD; fd < CONFIG_NFILE_DESCRIPTORS; fd++)
{
open_file_inode = files_get_openfile(fd);
if (open_file_inode && (open_file_inode == inode))
open_file_vnode = files_get_openfile(fd);
if (open_file_vnode && (open_file_vnode == vnode))
{
ret = files_close(fd);
if (ret < 0)
Executable → Regular
-48
View File
@@ -429,54 +429,6 @@ void inode_release(FAR struct inode *inode);
int foreach_inode(foreach_inode_t handler, FAR void *arg);
/****************************************************************************
* Name: files_initialize
*
* Description:
* This is called from the FS initialization logic to configure the files.
*
****************************************************************************/
void weak_function files_initialize(void);
/****************************************************************************
* Name: files_allocate
*
* Description:
* Allocate a struct files instance and associate it with an inode instance.
* Returns the file descriptor == index into the files array.
*
****************************************************************************/
int files_allocate(FAR struct inode *inode, int oflags, off_t pos,void *priv, int minfd);
/****************************************************************************
* Name: files_close
*
* Description:
* Close an inode (if open)
*
* Assumuptions:
* Caller holds the list semaphore because the file descriptor will be freed.
*
****************************************************************************/
int files_close(int fd);
/****************************************************************************
* Name: files_release
*
* Assumuptions:
* Similar to files_close(). Called only from open() logic on error
* conditions.
*
****************************************************************************/
void files_release(int fd);
int vfs_normalize_path(const char *directory, const char *filename, char **pathname);
int vfs_normalize_pathat(int fd, const char *filename, char **pathname);
#ifdef __cplusplus
#if __cplusplus
}
Executable → Regular
+21 -16
View File
@@ -49,7 +49,8 @@
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "limits.h"
#ifndef CONFIG_DISABLE_MOUNTPOINT
@@ -68,17 +69,17 @@
struct enum_mountpoint_s
{
foreach_mountpoint_t handler;
FAR void *arg;
void *arg;
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int mountpoint_filter(FAR struct inode *node,
FAR char dirpath[PATH_MAX], FAR void *arg)
#ifdef VFS_IMPL_LATER
static int mountpoint_filter(struct Vnode *node,
char dirpath[PATH_MAX], void *arg)
{
FAR struct enum_mountpoint_s *info = (FAR struct enum_mountpoint_s *)arg;
struct enum_mountpoint_s *info = (struct enum_mountpoint_s *)arg;
struct statfs statbuf;
int pathlen;
int namlen;
@@ -86,7 +87,7 @@ static int mountpoint_filter(FAR struct inode *node,
DEBUGASSERT(node && info && info->handler);
/* Check if the inode is a mountpoint. Mountpoints must support statfs.
/* Check if the vnode is a mountpoint. Mountpoints must support statfs.
* If this one does not for some reason, then it will be ignored.
*
* The root node is a special case: It has no operations (u.i_mops == NULL)
@@ -94,8 +95,8 @@ static int mountpoint_filter(FAR struct inode *node,
if (INODE_IS_MOUNTPT(node) && node->u.i_mops && node->u.i_mops->statfs)
{
/* Yes... get the full path to the inode by concatenating the inode
* name and the path to the directory containing the inode.
/* Yes... get the full path to the vnode by concatenating the vnode
* name and the path to the directory containing the vnode.
*/
pathlen = strlen(dirpath);
@@ -108,9 +109,9 @@ static int mountpoint_filter(FAR struct inode *node,
return -ENAMETOOLONG;
}
/* Append the inode name to the directory path */
/* Append the vnode name to the directory path */
ret = snprintf_s(&dirpath[pathlen], PATH_MAX - pathlen, PATH_MAX - pathlen - 1, "%s/", node->i_name);
ret = snprintf_s(&dirpath[pathlen], PATH_MAX - pathlen, PATH_MAX - pathlen - 1, "/%s", node->i_name);
if (ret < 0)
{
return -ENAMETOOLONG;
@@ -137,6 +138,7 @@ static int mountpoint_filter(FAR struct inode *node,
return ret;
}
#endif
/****************************************************************************
* Public Functions
@@ -150,8 +152,8 @@ static int mountpoint_filter(FAR struct inode *node,
* terminated when the callback 'handler' returns a non-zero value, or when
* all of the mountpoints have been visited.
*
* This is just a front end "filter" to foreach_inode() that forwards only
* mountpoint inodes. It is intended to support the mount() command to
* This is just a front end "filter" to foreach_vnode() that forwards only
* mountpoint vnodes. It is intended to support the mount() command to
* when the mount command is used to enumerate mounts.
*
* NOTE 1: Use with caution... The pseudo-file system is locked throughout
@@ -162,16 +164,19 @@ static int mountpoint_filter(FAR struct inode *node,
*
****************************************************************************/
int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg)
int foreach_mountpoint(foreach_mountpoint_t handler, void *arg)
{
#ifdef VFS_IMPL_LATER
struct enum_mountpoint_s info;
/* Let foreach_inode do the real work */
/* Let foreach_vnode do the real work */
info.handler = handler;
info.arg = arg;
return foreach_inode(mountpoint_filter, (FAR void *)&info);
return foreach_vnode(mountpoint_filter, (void *)&info);
#endif
return 0;
}
#endif
+62 -155
View File
@@ -40,15 +40,14 @@
#include "vfs_config.h"
#include "driver/driver.h"
#include "sys/mount.h"
#include "string.h"
#include "errno.h"
#include "assert.h"
#include "debug.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "stdlib.h"
#include "driver/driver.h"
#ifdef LOSCFG_DRIVERS_MTD
@@ -58,10 +57,15 @@
#include "errcode_fat.h"
#endif
#include "los_tables.h"
#ifdef LOSCFG_FS_ZPFS
#include "vfs_zpfs.h"
#ifdef LOSCFG_DRIVERS_RANDOM
#include "hisoc/random.h"
#else
#include "stdlib.h"
#endif
#include "fs/vfs_util.h"
#include "fs/path_cache.h"
#include "fs/mount.h"
/* At least one filesystem must be defined, or this file will not compile.
* It may be desire-able to make filesystems dynamically registered at
@@ -122,6 +126,7 @@ static const struct fsmap_t *mount_findfs(const char *filesystemtype)
return (const struct fsmap_t *)NULL;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -155,23 +160,20 @@ int mount(const char *source, const char *target,
const void *data)
{
int ret;
void *fshandle = NULL;
int errcode = 0;
char *fullpath = NULL;
char *fullpath_bak = NULL;
struct inode *blkdrvr_inode = NULL;
struct inode *mountpt_inode = NULL;
struct Mount* mnt = NULL;
struct Vnode *device = NULL;
struct Vnode *mountpt_vnode = NULL;
const struct fsmap_t *fsmap = NULL;
const struct mountpt_operations *mops = NULL;
const struct MountOps *mops = NULL;
LIST_HEAD *mount_list = NULL;
#ifdef LOSCFG_DRIVERS_MTD
mtd_partition *partition = NULL;
#endif
if (filesystemtype == NULL)
{
errcode = EINVAL;
errcode = -EINVAL;
goto errout;
}
@@ -179,23 +181,12 @@ int mount(const char *source, const char *target,
DEBUGASSERT(target && filesystemtype);
ret = vfs_normalize_path((const char *)NULL, target, &fullpath);
if (ret < 0)
{
PRINT_ERR("Failed to get fullpath,target: %s\n", target);
errcode = -ret;
goto errout;
}
fullpath_bak = fullpath;
/* Find the specified filesystem. Try the block driver file systems first */
if ((fsmap = mount_findfs(filesystemtype)) == NULL ||
(fsmap->is_bdfs && !source))
if ((fsmap = mount_findfs(filesystemtype)) == NULL || (fsmap->is_bdfs && !source))
{
PRINT_ERR("Failed to find file system %s\n", filesystemtype);
errcode = ENODEV;
free(fullpath_bak);
errcode = -ENODEV;
goto errout;
}
@@ -209,135 +200,77 @@ int mount(const char *source, const char *target,
/* Find the block driver */
ret = find_blockdriver(source, mountflags, &blkdrvr_inode);
ret = find_blockdriver(source, mountflags, &device);
if (ret < 0)
{
PRINT_ERR("Failed to find block driver %s\n", source);
errcode = -ret;
free(fullpath_bak);
errcode = ret;
goto errout;
}
}
/* Insert a dummy node -- we need to hold the inode semaphore
* to do this because we will have a momentarily bad structure.
*/
VnodeHold();
ret = VnodeLookup(target, &mountpt_vnode, 0);
inode_semtake();
#ifdef LOSCFG_FS_ZPFS
if (strcmp(filesystemtype, ZPFS_NAME) == 0)
{
ret = ZpfsPrepare(source, fullpath, &mountpt_inode, true);
if (ret < 0)
{
errcode = -ret;
goto errout_with_semaphore;
}
data = (const void *)mountpt_inode->i_private;
}
else
{
#endif
mountpt_inode = inode_search((const char **)&fullpath, (struct inode **)NULL, (struct inode **)NULL, \
(const char **)NULL);
/* The mount point must be an existed vnode. */
/* The mount point must be an existed inode. */
if (mountpt_inode == NULL)
if (ret != OK)
{
PRINT_ERR("Failed to find valid mountpoint %s\n", target);
errcode = EINVAL;
goto errout_with_semaphore;
errcode = -EINVAL;
goto errout_with_lock;
}
/* The mount point must be a dangling node with no children and
* no operations. If this inode is mounted, or it has children
* (except "/"), or it has operations, it cannot be mounted.
*/
if (INODE_IS_MOUNTPT(mountpt_inode) || (mountpt_inode->i_child && strcmp(target, "/")) || mountpt_inode->u.i_ops)
if (mountpt_vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)
{
PRINT_ERR("Can't to mount to this inode %s\n", target);
errcode = EINVAL;
goto errout_with_semaphore;
PRINT_ERR("can't mount to %s, already mounted.\n", target);
errcode = -EINVAL;
goto errout_with_lock;
}
#ifdef LOSCFG_FS_ZPFS
}
#endif
mountpt_inode ->mountflags = mountflags;
/* Bind the block driver to an instance of the file system. The file
* system returns a reference to some opaque, fs-dependent structure
* that encapsulates this binding.
*/
if (mops->bind == NULL)
if (mops->Mount == NULL)
{
/* The filesystem does not support the bind operation ??? */
fdbg("ERROR: Filesystem does not support bind\n");
errcode = EINVAL;
PRINTK("ERROR: Filesystem does not support bind\n");
errcode = -ENOSYS;
goto errout_with_mountpt;
}
/* Increment reference count for the reference we pass to the file system */
if (blkdrvr_inode != NULL)
{
blkdrvr_inode->i_crefs++;
/* On failure, the bind method returns -errorcode */
if (blkdrvr_inode->e_status != STAT_UNMOUNTED)
{
fdbg("ERROR: The node is busy\n");
errcode = EBUSY;
blkdrvr_inode->i_crefs--;
goto errout_with_mountpt;
}
}
#ifdef LOSCFG_DRIVERS_MTD
if (fsmap->is_mtd_support && (blkdrvr_inode != NULL))
if (fsmap->is_mtd_support && (device != NULL))
{
partition = (mtd_partition *)blkdrvr_inode->i_private;
partition = (mtd_partition *)((struct drv_data *)device->data)->priv;
partition->mountpoint_name = (char *)zalloc(strlen(target) + 1);
if (partition->mountpoint_name == NULL)
{
errcode = ENOMEM;
blkdrvr_inode->i_crefs--;
errcode = -ENOMEM;
goto errout_with_mountpt;
}
(void)strncpy_s(partition->mountpoint_name, strlen(target) + 1, target, strlen(target));
partition->mountpoint_name[strlen(target)] = '\0';
}
#endif
mountpt_inode ->mountflags = mountflags;
ret = mops->bind(blkdrvr_inode, data, &fshandle, fullpath_bak);
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
if (ret >= VIRERR_BASE)
{
errcode = ret;
}
else
#endif
mnt = MountAlloc(mountpt_vnode, (struct MountOps*)mops);
ret = mops->Mount(mnt, device, data);
if (ret != 0)
{
/* The inode is unhappy with the blkdrvr for some reason. Back out
/* The vnode is unhappy with the blkdrvr for some reason. Back out
* the count for the reference we failed to pass and exit with an
* error.
*/
fdbg("ERROR: Bind method failed: %d\n", ret);
if (blkdrvr_inode != NULL)
{
blkdrvr_inode->i_crefs--;
}
errcode = -ret;
errcode = ret;
#ifdef LOSCFG_DRIVERS_MTD
if (fsmap->is_mtd_support && (blkdrvr_inode != NULL) && (partition != NULL))
if (fsmap->is_mtd_support && (device != NULL) && (partition != NULL))
{
free(partition->mountpoint_name);
partition->mountpoint_name = NULL;
@@ -345,68 +278,42 @@ int mount(const char *source, const char *target,
#endif
goto errout_with_mountpt;
}
mnt->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_NEW;
mnt->vnodeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
mnt->ops = mops;
mnt->mountFlags = mountflags;
/* We have it, now populate it with driver specific information. */
//* We have it, now populate it with driver specific information. */
INODE_SET_MOUNTPT(mountpt_inode);
mount_list = GetMountList();
LOS_ListAdd(mount_list, &mnt->mountList);
mountpt_inode->u.i_mops = mops;
mountpt_inode->i_private = fshandle;
#ifdef LOSCFG_FILE_MODE
struct stat statinfo = {0};
if ((g_root_inode != mountpt_inode) && (stat(target, &statinfo) == 0))
if (!strcmp("/", target))
{
mountpt_inode->i_mode = statinfo.st_mode;
mountpt_inode->i_uid = statinfo.st_uid;
mountpt_inode->i_gid = statinfo.st_gid;
ChangeRoot(mnt->vnodeCovered);
}
#endif
VnodeDrop();
if (blkdrvr_inode)
{
blkdrvr_inode->e_status = STAT_MOUNTED;
}
inode_semgive();
/* We can release our reference to the blkdrver_inode, if the filesystem
* wants to retain the blockdriver inode (which it should), then it must
* have called inode_addref(). There is one reference on mountpt_inode
/* We can release our reference to the blkdrver_vnode, if the filesystem
* wants to retain the blockdriver vnode (which it should), then it must
* have called vnode_addref(). There is one reference on mountpt_vnode
* that will persist until umount() is called.
*/
if (blkdrvr_inode != NULL)
{
inode_release(blkdrvr_inode);
}
free(fullpath_bak);
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
if (errcode >= VIRERR_BASE)
{
set_errno(errcode);
}
#endif
return OK;
/* A lot of goto's! But they make the error handling much simpler */
errout_with_mountpt:
(void)inode_remove(fullpath);
errout_with_semaphore:
inode_semgive();
if (blkdrvr_inode != NULL)
if (mnt)
{
inode_release(blkdrvr_inode);
free(mnt);
}
free(fullpath_bak);
errout_with_lock:
VnodeDrop();
errout:
set_errno(errcode);
set_errno(-errcode);
return VFS_ERROR;
}
#endif /* CONFIG_FS_READABLE */
Regular → Executable
+73 -123
View File
@@ -42,35 +42,12 @@
#include "sys/mount.h"
#include "errno.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"
#include "disk.h"
#ifdef LOSCFG_FS_ZPFS
#include "vfs_zpfs.h"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
#include "fs_other.h"
/****************************************************************************
* Public Functions
@@ -94,15 +71,26 @@
*
****************************************************************************/
BOOL fs_in_use(struct Mount *mnt, const char *target)
{
char cwd[PATH_MAX];
char *pret = getcwd(cwd, PATH_MAX);
if (pret != NULL)
{
if (!strncmp(target, cwd, strlen(target)))
{
return TRUE;
}
}
return VnodeInUseIter(mnt->vnodeCovered);
}
int umount(const char *target)
{
FAR struct inode *mountpt_inode = NULL;
FAR struct inode *blkdrvr_inode = NULL;
int errcode = OK;
int status;
char *fullpath = NULL;
const char *relpath = NULL;
struct inode_search_s desc;
struct Vnode *mountpt_vnode = NULL;
struct Vnode *blkdrvr_vnode = NULL;
struct Vnode *covered_vnode = NULL;
struct Mount *mnt = NULL;
int ret;
#ifdef LOSCFG_FS_ZPFS
bool isZpfs = false;
@@ -113,117 +101,87 @@ int umount(const char *target)
if (target == NULL)
{
errcode = EFAULT;
goto errout;
}
/* Get a absolute path*/
errcode = vfs_normalize_path((const char *)NULL, target, &fullpath);
if (errcode < 0)
{
errcode = -errcode;
ret = -EFAULT;
goto errout;
}
/* Find the mountpt */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
VnodeHold();
ret = VnodeLookup(target, &mountpt_vnode, 0);
if (ret != OK || !mountpt_vnode)
{
errcode = EACCES;
free(fullpath);
goto errout;
}
mountpt_inode = desc.node;
relpath = desc.relpath;
/* Verify that the inode is a mountpoint */
if (!INODE_IS_MOUNTPT(mountpt_inode))
/* Verify that the vnode is a mountpoint */
if (!mountpt_vnode || !(mountpt_vnode->flag & VNODE_FLAG_MOUNT_ORIGIN))
{
errcode = EINVAL;
goto errout_with_mountpt;
ret = -EINVAL;
goto errout;
}
/* Verfy the path is a mountpoint path or file path*/
if ((relpath != NULL) && strlen(relpath))
/* Get mount point covered vnode and mount structure */
mnt = mountpt_vnode->originMount;
if (!mnt)
{
errcode = EPERM;
goto errout_with_mountpt;
ret = -EINVAL;
goto errout;
}
covered_vnode = mnt->vnodeBeCovered;
if (!covered_vnode || !(covered_vnode->flag & VNODE_FLAG_MOUNT_NEW))
{
ret = -EINVAL;
goto errout;
}
/* Unbind the block driver from the file system (destroying any fs
* private data.
*/
if (mountpt_inode->u.i_mops->unbind == NULL)
if (mnt->ops == NULL || mnt->ops->Unmount == NULL)
{
/* The filesystem does not support the unbind operation ??? */
errcode = EINVAL;
goto errout_with_mountpt;
ret = -EINVAL;
goto errout;
}
inode_semtake(); /* Hold the semaphore through the unbind logic */
#ifdef LOSCFG_FS_ZPFS
if (IsZpfsFileSystem(mountpt_inode))
if (IsZpfsFileSystem(mountpt_vnode))
{
isZpfs = true;
zpfsInode.i_private = mountpt_inode->i_private;
zpfsInode.u.i_ops = mountpt_inode->u.i_ops;
zpfsInode.i_flags = mountpt_inode->i_flags;
zpfsInode.i_private = mountpt_vnode->i_private;
zpfsInode.u.i_ops = mountpt_vnode->u.i_ops;
zpfsInode.i_flags = mountpt_vnode->i_flags;
}
#endif
if (mountpt_inode->i_crefs == 1)
/* Release the vnode under the mount point */
if (fs_in_use(mnt, target))
{
status = mountpt_inode->u.i_mops->unbind(mountpt_inode->i_private, &blkdrvr_inode);
if (status < 0)
{
/* The inode is unhappy with the blkdrvr for some reason */
errcode = -status;
goto errout_with_semaphore;
}
else if (status > 0)
{
errcode = EBUSY;
goto errout_with_semaphore;
}
}
else
{
errcode = EBUSY;
goto errout_with_semaphore;
}
/* Successfully unbound */
mountpt_inode->i_private = NULL;
mountpt_inode->u.i_ops= (const struct file_operations_vfs *)NULL;
mountpt_inode->i_flags = 0;
inode_release(mountpt_inode);
/* Successfully unbound, remove the mountpoint inode from
* the inode tree. The inode will not be deleted yet because
* there is still at least reference on it (from the mount)
*/
if (blkdrvr_inode)
{
blkdrvr_inode->e_status = STAT_UNMOUNTED;
ret = -EBUSY;
goto errout;
}
inode_semgive();
ret = VnodeFreeAll(mnt);
if (ret != OK)
{
goto errout;
}
/* Umount the filesystem */
ret = mnt->ops->Unmount(mnt, &blkdrvr_vnode);
if (ret != OK)
{
goto errout;
}
VnodeFree(mountpt_vnode);
LOS_ListDelete(&mnt->mountList);
free(mnt);
/* Did the unbind method return a contained block driver */
if (blkdrvr_inode)
if (blkdrvr_vnode)
{
inode_release(blkdrvr_inode);
; /* block driver operations after umount */
}
#ifdef LOSCFG_FS_ZPFS
@@ -232,23 +190,16 @@ int umount(const char *target)
ZpfsCleanUp((void*)&zpfsInode, fullpath);
}
#endif
covered_vnode->newMount = NULL;
covered_vnode->flag &= ~(VNODE_FLAG_MOUNT_NEW);
VnodeDrop();
free(fullpath);
return OK;
/* A lot of goto's! But they make the error handling much simpler */
errout_with_semaphore:
inode_semgive();
errout_with_mountpt:
mountpt_inode->i_crefs--;
if (blkdrvr_inode)
{
inode_release(blkdrvr_inode);
}
free(fullpath);
errout:
set_errno(errcode);
VnodeDrop();
set_errno(-ret);
return VFS_ERROR;
}
@@ -261,4 +212,3 @@ int umount2(const char* __target, int __flags)
}
return umount(__target);
}
+2634
View File
File diff suppressed because it is too large Load Diff
Executable → Regular
+3
View File
@@ -101,6 +101,9 @@ struct nfsmount
uint16_t nm_wsize; /* Max size of write RPC */
uint16_t nm_readdirsize; /* Size of a readdir RPC */
uint16_t nm_buflen; /* Size of I/O buffer */
mode_t nm_permission;
uint nm_gid;
uint nm_uid;
/* Set aside memory on the stack to hold the largest call message. NOTE
* that for the case of the write call message, it is the reply message that
Executable → Regular
+2
View File
@@ -81,6 +81,7 @@ struct nfsnode
uint8_t n_fhsize; /* Size in bytes of the file handle */
uint8_t n_flags; /* Node flags */
uint16_t n_mode; /* File mode for fstat() */
time_t n_atime; /* File access time */
time_t n_mtime; /* File modification time */
time_t n_ctime; /* File creation time */
nfsfh_t n_fhandle; /* NFS File Handle */
@@ -88,6 +89,7 @@ struct nfsnode
int n_oflags; /* Flags provided when file was opened */
loff_t n_fpos; /* NFS File position */
struct file *n_filep; /* File pointer from VFS */
char *n_name;
};
#ifdef __cplusplus
Executable → Regular
+27 -28
View File
@@ -57,11 +57,11 @@
* Private Functions
****************************************************************************/
static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer,
FAR char *terminator)
static inline int nfs_pathsegment(const char **path, char *buffer,
char *terminator)
{
FAR const char *src = *path;
FAR char *dest = buffer;
const char *src = *path;
char *dest = buffer;
int nbytes = 0;
char ch;
@@ -177,8 +177,8 @@ int nfs_checkmount(struct nfsmount *nmp)
****************************************************************************/
int nfs_request(struct nfsmount *nmp, int procnum,
FAR void *request, size_t reqlen,
FAR void *response, size_t resplen)
void *request, size_t reqlen,
void *response, size_t resplen)
{
struct rpcclnt *clnt = nmp->nm_rpcclnt;
struct nfs_reply_header replyh;
@@ -189,7 +189,7 @@ tryagain:
request, reqlen, response, resplen);
if (error != 0)
{
ferr("ERROR: rpcclnt_request failed: %d\n", error);
PRINTK("ERROR: rpcclnt_request failed: %d\n", error);
return error;
}
@@ -213,11 +213,10 @@ tryagain:
goto tryagain;
}
ferr("ERROR: NFS error %d from server\n", error);
PRINTK("ERROR: NFS error %d from server\n", error);
return error;
}
finfo("NFS_SUCCESS\n");
return OK;
}
@@ -235,12 +234,12 @@ tryagain:
*
****************************************************************************/
int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes)
int nfs_lookup(struct nfsmount *nmp, const char *filename,
struct file_handle *fhandle,
struct nfs_fattr *obj_attributes,
struct nfs_fattr *dir_attributes)
{
FAR uint32_t *ptr;
uint32_t *ptr = NULL;
uint32_t value;
int reqlen;
int namelen;
@@ -259,7 +258,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
/* Initialize the request */
ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.lookup.lookup;
ptr = (uint32_t *)&nmp->nm_msgbuffer.lookup.lookup;
reqlen = 0;
/* Copy the variable length, directory file handle */
@@ -283,8 +282,8 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
nfs_statistics(NFSPROC_LOOKUP);
error = nfs_request(nmp, NFSPROC_LOOKUP,
(FAR void *)&nmp->nm_msgbuffer.lookup, reqlen,
(FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
(void *)&nmp->nm_msgbuffer.lookup, reqlen,
(void *)nmp->nm_iobuffer, nmp->nm_buflen);
if (error)
{
@@ -297,7 +296,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
* may differ in size whereas struct rpc_reply_lookup uses a fixed size.
*/
ptr = (FAR uint32_t *)&((FAR struct rpc_reply_lookup *)nmp->nm_iobuffer)->lookup;
ptr = (uint32_t *)&((struct rpc_reply_lookup *)nmp->nm_iobuffer)->lookup;
/* Get the length of the file handle */
@@ -355,12 +354,12 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
*
****************************************************************************/
int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes)
int nfs_findnode(struct nfsmount *nmp, const char *relpath,
struct file_handle *fhandle,
struct nfs_fattr *obj_attributes,
struct nfs_fattr *dir_attributes)
{
FAR const char *path = relpath;
const char *path = relpath;
char buffer[NAME_MAX + 1];
char terminator;
uint32_t tmp;
@@ -464,11 +463,11 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
*
****************************************************************************/
int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
FAR struct file_handle *fhandle,
FAR struct nfs_fattr *attributes, FAR char *filename)
int nfs_finddir(struct nfsmount *nmp, const char *relpath,
struct file_handle *fhandle,
struct nfs_fattr *attributes, char *filename)
{
FAR const char *path = relpath;
const char *path = relpath;
uint32_t tmp;
char terminator;
int error;
@@ -553,7 +552,7 @@ int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
*
****************************************************************************/
void nfs_attrupdate(FAR struct nfsnode *np, FAR struct nfs_fattr *attributes)
void nfs_attrupdate(struct nfsnode *np, struct nfs_fattr *attributes)
{
struct timespec ts;
-3560
View File
File diff suppressed because it is too large Load Diff
Executable → Regular
+35 -35
View File
@@ -134,16 +134,16 @@ static struct rpcstats rpcstats;
* Private Function Prototypes
****************************************************************************/
static int rpcclnt_send(FAR struct rpcclnt *rpc, int procid, int prog,
FAR void *call, int reqlen);
static int rpcclnt_receive(FAR struct rpcclnt *rpc, struct sockaddr *aname,
static int rpcclnt_send(struct rpcclnt *rpc, int procid, int prog,
void *call, int reqlen);
static int rpcclnt_receive(struct rpcclnt *rpc, struct sockaddr *aname,
int proc, int program, void *reply, size_t resplen);
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
static int rpcclnt_reply(struct rpcclnt *rpc, int procid, int prog,
void *reply, size_t resplen);
static uint32_t rpcclnt_newxid(void);
static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
static void rpcclnt_fmtheader(struct rpc_call_header *ch,
uint32_t xid, int procid, int prog, int vers, size_t reqlen);
static int rpcclnt_reconnect(FAR struct rpcclnt *rpc, struct sockaddr *saddr);
static int rpcclnt_reconnect(struct rpcclnt *rpc, struct sockaddr *saddr);
/****************************************************************************
* Private Functions
@@ -160,8 +160,8 @@ static int rpcclnt_reconnect(FAR struct rpcclnt *rpc, struct sockaddr *saddr);
*
****************************************************************************/
static int rpcclnt_send(FAR struct rpcclnt *rpc, int procid, int prog,
FAR void *call, int reqlen)
static int rpcclnt_send(struct rpcclnt *rpc, int procid, int prog,
void *call, int reqlen)
{
ssize_t nbytes;
int ret = OK;
@@ -196,8 +196,8 @@ static int rpcclnt_send(FAR struct rpcclnt *rpc, int procid, int prog,
*
****************************************************************************/
static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
int proc, int program, FAR void *reply,
static int rpcclnt_receive(struct rpcclnt *rpc, struct sockaddr *aname,
int proc, int program, void *reply,
size_t resplen)
{
ssize_t nbytes;
@@ -261,8 +261,8 @@ retry:
*
****************************************************************************/
static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
int proc, int program, FAR void *reply,
static int rpcclnt_receive(struct rpcclnt *rpc, struct sockaddr *aname,
int proc, int program, void *reply,
size_t resplen)
{
ssize_t nbytes;
@@ -350,8 +350,8 @@ static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
*
****************************************************************************/
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
FAR void *reply, size_t resplen)
static int rpcclnt_reply(struct rpcclnt *rpc, int procid, int prog,
void *reply, size_t resplen)
{
int error;
@@ -378,8 +378,8 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
else
{
FAR struct rpc_reply_header *replyheader =
(FAR struct rpc_reply_header *)reply;
struct rpc_reply_header *replyheader =
(struct rpc_reply_header *)reply;
if (replyheader->rp_direction != rpc_reply)
{
@@ -501,7 +501,7 @@ static int rpcclnt_alivecheck(struct rpcclnt *rpc)
*
****************************************************************************/
static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
static void rpcclnt_fmtheader(struct rpc_call_header *ch,
uint32_t xid, int prog, int vers, int procid, size_t reqlen)
{
unsigned int high = 0;
@@ -545,7 +545,7 @@ static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
ch->rpc_verf.authlen = 0;
}
static int rpcclnt_reconnect(FAR struct rpcclnt *rpc, struct sockaddr *saddr)
static int rpcclnt_reconnect(struct rpcclnt *rpc, struct sockaddr *saddr)
{
int errval;
int error;
@@ -732,15 +732,15 @@ int rpcclnt_connect(struct rpcclnt *rpc)
request.sdata.pmap.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&request.sdata, sizeof(struct call_args_pmap),
(FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
(void *)&request.sdata, sizeof(struct call_args_pmap),
(void *)&response.rdata, sizeof(struct rpc_reply_pmap));
if (error != 0)
{
ferr("ERROR: rpcclnt_request failed: %d\n", error);
goto bad;
}
sa = (FAR struct sockaddr_in *)saddr;
sa = (struct sockaddr_in *)saddr;
sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
error = rpcclnt_reconnect(rpc, saddr);
@@ -768,9 +768,9 @@ int rpcclnt_connect(struct rpcclnt *rpc)
request.mountd.mount.len = txdr_unsigned(sizeof(request.mountd.mount.rpath));
error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER3,
(FAR void *)&request.mountd,
(void *)&request.mountd,
sizeof(struct call_args_mount),
(FAR void *)&response.mdata,
(void *)&response.mdata,
sizeof(struct rpc_reply_mount));
if (error != 0)
{
@@ -807,9 +807,9 @@ int rpcclnt_connect(struct rpcclnt *rpc)
request.sdata.pmap.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&request.sdata,
(void *)&request.sdata,
sizeof(struct call_args_pmap),
(FAR void *)&response.rdata,
(void *)&response.rdata,
sizeof(struct rpc_reply_pmap));
if (error != 0)
{
@@ -878,7 +878,7 @@ int rpcclnt_umount(struct rpcclnt *rpc)
int error;
saddr = rpc->rc_name;
sa = (FAR struct sockaddr_in *)saddr;
sa = (struct sockaddr_in *)saddr;
/* Do the RPC to get a dynamic bounding with the server using ppmap.
* Get port number for MOUNTD.
@@ -899,9 +899,9 @@ int rpcclnt_umount(struct rpcclnt *rpc)
request.sdata.pmap.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&request.sdata,
(void *)&request.sdata,
sizeof(struct call_args_pmap),
(FAR void *)&response.rdata,
(void *)&response.rdata,
sizeof(struct rpc_reply_pmap));
if (error != 0)
{
@@ -926,9 +926,9 @@ int rpcclnt_umount(struct rpcclnt *rpc)
request.mountd.umount.len = txdr_unsigned(sizeof(request.mountd.umount.rpath));
error = rpcclnt_request(rpc, RPCMNT_UMOUNT, RPCPROG_MNT, RPCMNT_VER3,
(FAR void *)&request.mountd,
(void *)&request.mountd,
sizeof(struct call_args_umount),
(FAR void *)&response.mdata,
(void *)&response.mdata,
sizeof(struct rpc_reply_umount));
if (error != 0)
{
@@ -960,9 +960,9 @@ bad:
*
****************************************************************************/
int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
int version, FAR void *request, size_t reqlen,
FAR void *response, size_t resplen)
int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog,
int version, void *request, size_t reqlen,
void *response, size_t resplen)
{
struct rpc_reply_header *replymsg;
uint32_t tmp;
@@ -983,7 +983,7 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
/* Initialize the RPC header fields */
rpcclnt_fmtheader((FAR struct rpc_call_header *)request,
rpcclnt_fmtheader((struct rpc_call_header *)request,
rpc->xid, prog, version, procnum, reqlen);
/* Send the RPC call messsages and receive the RPC response. For UDP-RPC, A limited
@@ -1081,7 +1081,7 @@ int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
/* Break down the RPC header and check if it is OK */
replymsg = (FAR struct rpc_reply_header *)response;
replymsg = (struct rpc_reply_header *)response;
tmp = fxdr_unsigned(uint32_t, replymsg->type);
if (tmp == RPC_MSGDENIED)
+649 -541
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -177,9 +177,11 @@ struct tmpfs_file_s
struct tmpfs_s
{
/* The root directory */
FAR struct tmpfs_dirent_s tfs_root;
struct tmpfs_sem_s tfs_exclsem;
mode_t permission;
uint gid;
uint uid;
};
/* This is the type used the tmpfs_statfs_callout to accumulate memory usage */
Executable → Regular
-1
View File
@@ -48,7 +48,6 @@
# include "net/net.h"
#endif
#include "inode/inode.h"
#include "mqueue.h"
/****************************************************************************
+1 -1
View File
@@ -44,7 +44,7 @@
#include "sched.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "net/net.h"
/****************************************************************************
+1 -2
View File
@@ -43,8 +43,7 @@
#include "errno.h"
#include "unistd.h"
#include "sched.h"
#include "inode/inode.h"
#include "fs/vnode.h"
/* This logic in this applies only when both socket and file descriptors are
* in that case, this function descriminates which type of dup2 is being
Executable → Regular
+16 -28
View File
@@ -47,7 +47,7 @@
#include "fs/fs.h"
#include "fs/file.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "stdlib.h"
#include "string.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
@@ -74,19 +74,18 @@
*
****************************************************************************/
int file_dup(FAR struct file *filep, int minfd)
int file_dup(struct file *filep, int minfd)
{
int fd2;
int ret;
int err,len;
int err,len,rellen;
struct file *filep2 = NULL;
char *fullpath = NULL;
const char *relpath = NULL;
struct inode_search_s desc;
char *relpath = NULL;
/* Verify that fd is a valid, open file descriptor */
if ((filep->f_inode == NULL) || (filep->f_path == NULL))
if ((filep->f_vnode == NULL) || (filep->f_path == NULL))
{
set_errno(EBADF);
return VFS_ERROR;
@@ -100,12 +99,11 @@ int file_dup(FAR struct file *filep, int minfd)
return VFS_ERROR;
}
/* Then allocate a new file descriptor for the inode */
/* Then allocate a new file descriptor for the vnode */
fd2 = files_allocate(filep->f_inode, filep->f_oflags, filep->f_pos, filep->f_priv, minfd);
fd2 = files_allocate(filep->f_vnode, filep->f_oflags, filep->f_pos, filep->f_priv, minfd);
if (fd2 < 0)
{
inode_release(filep->f_inode);
free(fullpath);
set_errno(EMFILE);
return VFS_ERROR;
@@ -114,39 +112,29 @@ int file_dup(FAR struct file *filep, int minfd)
ret = fs_getfilep(fd2, &filep2);
(void)strncpy_s(fullpath, len + 1, filep->f_path, len);
SETUP_SEARCH(&desc, fullpath, false);
if (inode_find(&desc) < 0)
if (filep->f_relpath != NULL)
{
ret = -EACCES;
goto errout_with_inode;
rellen = strlen(filep->f_relpath);
relpath = (char *)zalloc(rellen + 1);
(void)strncpy_s(relpath, rellen + 1, filep->f_relpath, rellen);
}
relpath = desc.relpath;
filep2->f_path = fullpath;
filep2->f_relpath = relpath;
if (filep->f_inode->u.i_mops && filep->f_inode->u.i_mops->dup)
{
ret = filep->f_inode->u.i_mops->dup(filep, filep2);
}
else
{
ret = -ENOSYS;
}
filep2->f_priv = filep->f_priv;
if (ret < 0)
{
goto errout_with_inode;
goto errout_with_vnode;
}
return fd2;
errout_with_inode:
errout_with_vnode:
clear_fd(fd2);
inode_release(filep2->f_inode);
free(fullpath);
filep2->f_oflags = 0;
filep2->f_pos = 0;
filep2->f_inode = NULL;
filep2->f_vnode = NULL;
filep2->f_priv = NULL;
filep2->f_path = NULL;
filep2->f_relpath = NULL;
@@ -175,7 +163,7 @@ errout_with_inode:
int fs_dupfd(int fd, int minfd)
{
FAR struct file *filep;
struct file *filep;
/* Get the file structure corresponding to the file descriptor. */
Executable → Regular
+4 -4
View File
@@ -44,7 +44,7 @@
#include "unistd.h"
#include "sched.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
@@ -82,8 +82,8 @@ int fs_dupfd2(int fd1, int fd2)
int dup2(int fd1, int fd2)
#endif
{
FAR struct file *filep1;
FAR struct file *filep2;
struct file *filep1;
struct file *filep2;
int ret;
/* Get the file structures corresponding to the file descriptors. */
@@ -103,7 +103,7 @@ int dup2(int fd1, int fd2)
/* Verify that fd1 is a valid, open file descriptor */
if (filep1->f_inode == NULL)
if (filep1->f_vnode == NULL)
{
set_errno(EBADF);
return VFS_ERROR;
Executable → Regular
+5 -5
View File
@@ -45,7 +45,7 @@
#include "errno.h"
#include "assert.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#if defined(LOSCFG_NET_LWIP_SACK)
#include "lwip/sockets.h"
@@ -81,14 +81,14 @@
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int file_vfcntl(FAR struct file *filep, int cmd, va_list ap)
int file_vfcntl(struct file *filep, int cmd, va_list ap)
{
int err = 0;
int ret = OK;
/* Was this file opened ? */
if (!filep || !filep->f_inode)
if (!filep || !filep->f_vnode)
{
err = EBADF;
goto errout;
@@ -257,7 +257,7 @@ errout:
int fcntl(int fd, int cmd, ...)
{
FAR struct file *filep;
struct file *filep = NULL;
va_list ap;
int ret;
int val = 0;
@@ -319,7 +319,7 @@ int fcntl(int fd, int cmd, ...)
int fcntl64(int fd, int cmd, ...)
{
FAR struct file *filep = NULL;
struct file *filep = NULL;
va_list va_ap;
int reval;
int va_val = 0;
Executable → Regular
+7 -13
View File
@@ -48,9 +48,7 @@
#include "fs/fs.h"
#include "inode/inode.h"
#ifndef CONFIG_DISABLE_MOUNTPOINT
#include "fs/vnode.h"
/****************************************************************************
* Public Functions
@@ -66,9 +64,8 @@
*
****************************************************************************/
int file_fsync(FAR struct file *filep)
int file_fsync(struct file *filep)
{
struct inode *inode;
int ret;
/* Was this file opened for write access? */
@@ -79,14 +76,12 @@ int file_fsync(FAR struct file *filep)
goto errout;
}
/* Is this inode a registered mountpoint? Does it support the
/* Is this vnode a registered mountpoint? Does it support the
* sync operations may be relevant to device drivers but only
* the mountpoint operations vtable contains a sync method.
*/
inode = filep->f_inode;
if (!inode || !INODE_IS_MOUNTPT(inode) ||
!inode->u.i_mops || !inode->u.i_mops->sync)
if (!filep || !filep->ops || !filep->ops->fsync)
{
ret = EINVAL;
goto errout;
@@ -94,7 +89,7 @@ int file_fsync(FAR struct file *filep)
/* Yes, then tell the mountpoint to sync this file */
ret = inode->u.i_mops->sync(filep);
ret = filep->ops->fsync(filep);
if (ret >= 0)
{
return OK;
@@ -111,13 +106,13 @@ errout:
* Name: fsync
*
* Description:
* This func simply binds inode sync methods to the sync system call.
* This func simply binds vnode sync methods to the sync system call.
*
****************************************************************************/
int fsync(int fd)
{
FAR struct file *filep;
struct file *filep = NULL;
/* Get the file structure corresponding to the file descriptor. */
@@ -133,4 +128,3 @@ int fsync(int fd)
return file_fsync(filep);
}
#endif /* !CONFIG_DISABLE_MOUNTPOINT */
Executable → Regular
+9 -5
View File
@@ -41,9 +41,12 @@
#include "sys/types.h"
#include "errno.h"
#include "unistd.h"
#include "console.h"
#include "sched.h"
#include "inode/inode.h"
#include "sys/types.h"
#include "fs/vnode.h"
#include "vfs_config.h"
/****************************************************************************
* Public Functions
@@ -67,7 +70,7 @@
*
****************************************************************************/
int fs_getfilep_normal(int fd, FAR struct file **filep)
static int fs_getfilep_normal(int fd, struct file **filep)
{
struct filelist *list;
@@ -102,12 +105,13 @@ int fs_getfilep_normal(int fd, FAR struct file **filep)
return OK;
}
int fs_getfilep(int fd, FAR struct file **filep)
int fs_getfilep(int fd, struct file **filep)
{
int ret = fs_getfilep_normal(fd, filep);
if (ret < 0)
{
set_errno(-ret);
return VFS_ERROR;
}
return ret;
return OK;
}
Executable → Regular
+6 -8
View File
@@ -49,7 +49,7 @@
# include "net/net.h"
#endif
#include "inode/inode.h"
#include "fs/vnode.h"
/****************************************************************************
* Public Functions
@@ -94,8 +94,7 @@ int ioctl(int fd, int req, ...)
UINTPTR arg = 0;
va_list ap;
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct file *filep;
FAR struct inode *inode;
struct file *filep;
int ret = OK;
#endif
@@ -149,12 +148,11 @@ int ioctl(int fd, int req, ...)
/* Is a driver registered? Does it support the ioctl method? */
inode = filep->f_inode;
if (inode && inode->u.i_ops && inode->u.i_ops->ioctl)
if (filep->ops && filep->ops->ioctl)
{
/* Yes, then let it perform the ioctl */
ret = (int)inode->u.i_ops->ioctl(filep, req, arg);
ret = (int) filep->ops->ioctl(filep, req, arg);
if (ret < 0)
{
err = -ret;
@@ -163,7 +161,7 @@ int ioctl(int fd, int req, ...)
}
else
{
err = EBADF;
err = ENOSYS;
ret = VFS_ERROR;
goto errout;
}
@@ -173,5 +171,5 @@ int ioctl(int fd, int req, ...)
errout:
set_errno(err);
return ret;
return VFS_ERROR;
}
Executable → Regular
+22 -23
View File
@@ -44,7 +44,7 @@
#include "sched.h"
#include "assert.h"
#include "errno.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
@@ -70,36 +70,37 @@
*
****************************************************************************/
off_t file_seek(FAR struct file *filep, off_t offset, int whence)
off_t file_seek(struct file *filep, off_t offset, int whence)
{
FAR struct inode *inode;
int ret;
struct Vnode *vnode;
int err = OK;
off_t pos;
DEBUGASSERT(filep);
inode = filep->f_inode;
vnode = filep->f_vnode;
if (!inode)
if (!vnode)
{
err = EBADF;
err = -EBADF;
goto errout;
}
/* Invoke the file seek method if available */
if (inode->u.i_ops && inode->u.i_ops->seek)
if (filep->ops != NULL && filep->ops->seek != NULL)
{
ret = inode->u.i_ops->seek(filep, offset, whence);
if (ret < 0)
pos = filep->ops->seek(filep, offset, whence);
if (pos < 0)
{
err = -ret;
err = pos;
goto errout;
}
else
{
filep->f_pos = pos;
}
}
else
{
/* No... Just set the common file position value */
{ /* No... Just set the common file position value */
switch (whence)
{
case SEEK_CUR:
@@ -114,25 +115,24 @@ off_t file_seek(FAR struct file *filep, off_t offset, int whence)
}
else
{
err = EINVAL;
err = -EINVAL;
goto errout;
}
break;
case SEEK_END:
err = ENOSYS;
err = -ENOSYS;
goto errout;
default:
err = EINVAL;
err = -EINVAL;
goto errout;
}
}
}
return (off_t)filep->f_pos;
errout:
set_errno(err);
set_errno(-err);
return (off_t)VFS_ERROR;
}
@@ -175,7 +175,7 @@ errout:
off_t lseek(int fd, off_t offset, int whence)
{
FAR struct file *filep;
struct file *filep;
/* Get the file structure corresponding to the file descriptor. */
@@ -190,5 +190,4 @@ off_t lseek(int fd, off_t offset, int whence)
return file_seek(filep, offset, whence);
}
#endif
Executable → Regular
+21 -21
View File
@@ -44,7 +44,7 @@
#include "sched.h"
#include "assert.h"
#include "errno.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
@@ -70,37 +70,38 @@
*
****************************************************************************/
off64_t file_seek64(FAR struct file *filep, off64_t offset, int whence)
off64_t file_seek64(struct file *filep, off64_t offset, int whence)
{
FAR struct inode *inode = NULL;
off64_t ret;
struct Vnode *vnode = NULL;
int err = OK;
off64_t pos;
DEBUGASSERT(filep);
inode = filep->f_inode;
vnode = filep->f_vnode;
if (inode == NULL)
if (vnode == NULL)
{
err = EBADF;
err = -EBADF;
goto errout;
}
/* Invoke the file seek method if available */
if (INODE_IS_MOUNTPT(inode) && inode->u.i_mops && inode->u.i_mops->seek64)
if (filep->ops != NULL && filep->ops->seek != NULL)
{
ret = inode->u.i_mops->seek64(filep, offset, whence);
if (ret < 0)
pos = filep->ops->seek(filep, offset, whence);
if (pos < 0)
{
err = -(int)ret;
err = pos;
goto errout;
}
filep->f_pos = ret;
else
{
filep->f_pos = pos;
}
}
else
{
/* No... Just set the common file position value */
{ /* No... Just set the common file position value */
switch (whence)
{
case SEEK_CUR:
@@ -115,17 +116,17 @@ off64_t file_seek64(FAR struct file *filep, off64_t offset, int whence)
}
else
{
err = EINVAL;
err = -EINVAL;
goto errout;
}
break;
case SEEK_END:
err = ENOSYS;
err = -ENOSYS;
goto errout;
default:
err = EINVAL;
err = -EINVAL;
goto errout;
}
}
@@ -133,7 +134,7 @@ off64_t file_seek64(FAR struct file *filep, off64_t offset, int whence)
return filep->f_pos;
errout:
set_errno(err);
set_errno(-err);
return (off64_t)VFS_ERROR;
}
@@ -176,7 +177,7 @@ errout:
off64_t lseek64(int fd, off64_t offset, int whence)
{
FAR struct file *filep;
struct file *filep;
/* Get the file structure corresponding to the file descriptor. */
@@ -191,5 +192,4 @@ off64_t lseek64(int fd, off64_t offset, int whence)
return file_seek64(filep, offset, whence);
}
#endif
Executable → Regular
+69 -158
View File
@@ -43,47 +43,24 @@
#include "sys/stat.h"
#include "fs/fs.h"
#include "stdlib.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "string.h"
#include "fs_other.h"
#include "capability_api.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_MKDIR
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_MKDIR 1
#endif
#ifdef FS_HAVE_MKDIR
#include "fs/path_cache.h"
#include "fs/vfs_util.h"
/****************************************************************************
* Private Functions
****************************************************************************/
int do_mkdir(int dirfd, const char *pathname, mode_t mode)
{
FAR struct inode *inode;
FAR struct inode *pathnode;
const char *relpath = NULL;
int errcode;
int ret;
char *fullpath = NULL;
char *relativepath = NULL;
struct inode_search_s desc;
uint c_uid = OsCurrUserGet()->effUserID;
uint c_gid = OsCurrUserGet()->effGid;
struct Vnode *parentVnode = NULL;
struct Vnode *vnode = NULL;
int ret;
char *fullpath = NULL;
char *relativepath = NULL;
char *dirname = NULL;
mode &= ~GetUmask();
mode &= (S_IRWXU|S_IRWXG|S_IRWXO);
@@ -92,7 +69,6 @@ int do_mkdir(int dirfd, const char *pathname, mode_t mode)
ret = get_path_from_fd(dirfd, &relativepath);
if (ret < 0)
{
errcode = -ret;
goto errout;
}
@@ -104,145 +80,82 @@ int do_mkdir(int dirfd, const char *pathname, mode_t mode)
if (ret < 0)
{
errcode = -ret;
goto errout;
}
/* Find the inode that includes this path */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
inode = desc.node;
relpath = desc.relpath;
if ((ret >= 0) && (inode != NULL))
if (!strncmp(fullpath, "/dev", 4) || !strncmp(fullpath, "/proc", 5))
{
if (!strlen(relpath))
// virtual root create virtual dir
VnodeHold();
ret = VnodeLookup(fullpath, &vnode, V_DUMMY|V_CREATE);
if (ret != OK)
{
/* Find the inode that exactly match this path. */
errcode = EEXIST;
goto errout_with_inode;
goto errout_with_lock;
}
/* If the path doesn't include the existed rootfs dirs,
* then make a pseudo dir.
*/
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
if (((inode == g_root_inode) && !IsInRootfs(relpath)) || (!INODE_IS_MOUNTPT(g_root_inode)))
{
if (VfsPermissionCheck(desc.parent->i_uid, desc.parent->i_gid, desc.parent->i_mode, EXEC_OP | WRITE_OP))
{
errcode = EACCES;
goto errout_with_inode;
}
/* Create a pseudo inode. */
inode_semtake();
ret = inode_reserve(fullpath, &pathnode);
if (ret < 0)
{
errcode = -ret;
inode_semgive();
goto errout_with_inode;
}
pathnode->i_mode = mode;
pathnode->i_uid = c_uid;
pathnode->i_gid = c_gid;
inode_semgive();
}
else
#endif
/* An inode was found that includes this path and possibly refers to a
* mountpoint.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
/* Check if the inode is a valid mountpoint. */
if (!INODE_IS_MOUNTPT(inode) || !inode->u.i_mops)
{
/* The inode is not a mountpoint */
errcode = EEXIST;
goto errout_with_inode;
}
/* Perform the mkdir operation using the relative path
* at the mountpoint.
*/
else if (inode->u.i_mops->mkdir)
{
ret = inode->u.i_mops->mkdir(inode, relpath, mode);
if (ret < 0)
{
errcode = -ret;
goto errout_with_inode;
}
}
else
{
errcode = ENOSYS;
goto errout_with_inode;
}
/* Release our reference on the inode */
inode_release(inode);
#else
/* But mountpoints are not supported in this configuration */
errcode = EEXIST;
goto errout_with_inode;
#endif
vnode->mode = mode | S_IFDIR;
vnode->type = VNODE_TYPE_DIR;
VnodeDrop();
goto out;
}
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* No inode exists that contains this path. Create a new inode in the
* pseudo-filesystem at this location.
*/
dirname = strrchr(fullpath, '/') + 1;
VnodeHold();
ret = VnodeLookup(fullpath, &parentVnode, 0);
if (ret == OK)
{
ret = -EEXIST;
goto errout_with_lock;
}
if (parentVnode == NULL)
{
ret = -ENOENT;
goto errout_with_lock;
}
parentVnode->useCount++;
if (VfsVnodePermissionCheck(parentVnode, WRITE_OP))
{
ret = -EACCES;
goto errout_with_count;
}
if ((parentVnode->vop != NULL) && (parentVnode->vop->Mkdir != NULL))
{
ret = parentVnode->vop->Mkdir(parentVnode, dirname, mode, &vnode);
}
else
{
/* Create an inode in the pseudo-filesystem at this path.
* NOTE that the new inode will be created with a reference
* count of zero.
*/
inode_semtake();
ret = inode_reserve(fullpath, &inode);
if (ret < 0)
{
errcode = -ret;
free(fullpath);
inode_semgive();
goto errout;
}
inode->i_mode = mode;
inode->i_uid = c_uid;
inode->i_gid = c_gid;
inode_semgive();
ret = -ENOSYS;
}
#else
else
{
errcode = ENXIO;
free(fullpath);
goto errout;
}
#endif
if (ret < 0)
{
goto errout_with_count;
}
struct PathCache *dt = PathCacheAlloc(parentVnode, vnode, dirname, strlen(dirname));
if (dt == NULL) {
// alloc name cache failed is not a critical problem, let it go.
PRINT_ERR("alloc path cache %s failed\n", dirname);
}
parentVnode->useCount--;
VnodeDrop();
out:
/* Directory successfully created */
free(fullpath);
return OK;
errout_with_inode:
inode_release(inode);
free(fullpath);
errout_with_count:
parentVnode->useCount--;
errout_with_lock:
VnodeDrop();
errout:
set_errno(errcode);
set_errno(-ret);
if (fullpath)
{
free(fullpath);
}
return VFS_ERROR;
}
@@ -273,5 +186,3 @@ int mkdirat(int dirfd, const char *pathname, mode_t mode)
{
return do_mkdir(dirfd, pathname, mode);
}
#endif /* FS_HAVE_MKDIR */
+201 -161
View File
@@ -50,10 +50,12 @@
#endif
#include "stdlib.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "driver/blockproxy.h"
#include "fs_other.h"
#include "fs/vfs_util.h"
#include "fs/path_cache.h"
#include "unistd.h"
/****************************************************************************
* Public Functions
@@ -97,7 +99,7 @@ static int oflag_convert_mode(int oflags)
int get_path_from_fd(int fd, char **path)
{
FAR struct file *file = NULL;
struct file *file = NULL;
char *copypath = NULL;
if (fd == AT_FDCWD)
@@ -111,7 +113,7 @@ int get_path_from_fd(int fd, char **path)
return -ENOENT;
}
if ((file == NULL) || (file->f_inode == NULL) || (file->f_path == NULL))
if ((file == NULL) || (file->f_vnode == NULL) || (file->f_path == NULL))
{
return -EBADF;
}
@@ -141,39 +143,190 @@ int get_path_from_fd(int fd, char **path)
return -ENOENT;
}
int do_open(int dirfd, const char *path, int oflags, ...)
static int do_creat(struct Vnode **node, char *fullpath, mode_t mode)
{
int ret;
struct Vnode *parentNode = *node;
char *name = strrchr(fullpath, '/') + 1;
if (parentNode->vop != NULL && parentNode->vop->Create != NULL)
{
ret = parentNode->vop->Create(parentNode, name, mode, node);
}
else
{
ret = -ENOSYS;
}
if (ret < 0)
{
return ret;
}
struct PathCache *dt = PathCacheAlloc(parentNode, *node, name, strlen(name));
if (dt == NULL)
{
// alloc name cache failed is not a critical problem, let it go.
PRINT_ERR("alloc path cache %s failed\n", name);
}
return OK;
}
int fp_open(char *fullpath, int oflags, mode_t mode)
{
FAR struct file *filep = NULL;
FAR struct inode *inode = NULL;
FAR const char *relpath = NULL;
char *fullpath = NULL;
char *relativepath = NULL;
struct inode_search_s desc;
#if defined(LOSCFG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT)
mode_t mode = DEFAULT_FILE_MODE;
#endif
int ret;
int fd;
int acc_mode;
#ifdef LOSCFG_FILE_MODE
/* If the file is opened for creation, then get the mode bits */
int accmode;
struct file *filep = NULL;
struct Vnode *vnode = NULL;
if ((oflags & (O_WRONLY | O_CREAT)) != 0)
VnodeHold();
ret = VnodeLookup(fullpath, &vnode, 0);
if (ret == OK)
{
va_list ap;
va_start(ap, oflags);
mode = va_arg(ap, int);
va_end(ap);
mode &= ~GetUmask();
mode &= (S_IRWXU|S_IRWXG|S_IRWXO);
/* if file exist */
if (vnode->type == VNODE_TYPE_BCHR)
{
ret = -EINVAL;
goto errout_without_count;
}
if (vnode->type == VNODE_TYPE_BLK) {
fd = block_proxy(fullpath, oflags);
VnodeDrop();
if (fd < 0)
{
ret = fd;
goto errout_without_count;
}
return fd;
}
if ((oflags & O_CREAT) && (oflags & O_EXCL))
{
ret = -EEXIST;
VnodeDrop();
goto errout_without_count;
}
if (vnode->type == VNODE_TYPE_DIR)
{
ret = -EISDIR;
VnodeDrop();
goto errout_without_count;
}
accmode = oflag_convert_mode(oflags);
if (VfsVnodePermissionCheck(vnode, accmode))
{
ret = -EACCES;
VnodeDrop();
goto errout_without_count;
}
}
#endif
if ((ret != OK) && (oflags & O_CREAT) && vnode)
{
/* if file not exist, but parent dir of the file is exist */
if (VfsVnodePermissionCheck(vnode, WRITE_OP))
{
ret = -EACCES;
VnodeDrop();
goto errout_without_count;
}
ret = do_creat(&vnode, fullpath, mode);
if (ret != OK)
{
VnodeDrop();
goto errout_without_count;
}
}
if (ret != OK)
{
/* found nothing */
VnodeDrop();
goto errout_without_count;
}
vnode->useCount++;
VnodeDrop();
if (oflags & O_TRUNC)
{
if (vnode->useCount > 1)
{
ret = -EBUSY;
goto errout;
}
if (vnode->vop->Truncate)
{
ret = vnode->vop->Truncate(vnode, 0);
if (ret != OK)
{
goto errout;
}
}
else
{
ret = -ENOSYS;
goto errout;
}
}
fd = files_allocate(vnode, oflags, 0, NULL, 3); /* 3: file start fd */
if (fd < 0)
{
ret = -EMFILE;
goto errout;
}
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
files_release(fd);
ret = -get_errno();
goto errout;
}
filep->f_vnode = vnode;
filep->ops = vnode->fop;
filep->f_path = fullpath;
if (filep->ops && filep->ops->open)
{
ret = filep->ops->open(filep);
}
if (ret < 0)
{
files_release(fd);
goto errout;
}
/* we do not bother to handle the NULL scenario, if so, page-cache feature will not be used
* when we do the file fault */
add_mapping(filep, fullpath);
return fd;
errout:
VnodeHold();
vnode->useCount--;
VnodeDrop();
errout_without_count:
set_errno(-ret);
return VFS_ERROR;
}
int do_open(int dirfd, const char *path, int oflags, mode_t mode)
{
int ret;
int fd;
char *fullpath = NULL;
char *relativepath = NULL;
/* Get relative path by dirfd*/
ret = get_path_from_fd(dirfd, &relativepath);
if (ret < 0)
{
ret = -ret;
goto errout;
}
@@ -182,132 +335,26 @@ int do_open(int dirfd, const char *path, int oflags, ...)
{
free(relativepath);
}
if (ret < 0)
{
ret = -ret;
goto errout;
}
/* Get an inode for this file */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
{
ret = EACCES;
free(fullpath);
goto errout;
}
inode = desc.node;
relpath = desc.relpath;
#if !defined(CONFIG_DISABLE_MOUNTPOINT)
#ifdef LOSCFG_FS_VFS_BLOCK_DEVICE
if (INODE_IS_BLOCK(inode))
{
fd = block_proxy(path, oflags);
if (fd < 0)
{
ret = fd;
goto errout_with_inode;
}
inode_release(inode);
free(fullpath);
return fd;
}
#endif
#endif
/* Verify that the inode is valid and either a "normal" character driver or a
* mountpoint. We specifically exclude block drivers and and "special"
* inodes (semaphores, message queues, shared memory).
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
if ((!INODE_IS_DRIVER(inode) && !INODE_IS_MOUNTPT(inode)) || !inode->u.i_ops)
#else
if (!INODE_IS_DRIVER(inode) || !inode->u.i_ops)
#endif
{
ret = ENXIO;
goto errout_with_inode;
}
/* Associate the inode with a file structure */
fd = files_allocate(inode, oflags, 0, NULL, 3); /* 3: file start fd */
fd = fp_open(fullpath, oflags, mode);
if (fd < 0)
{
ret = EMFILE;
goto errout_with_inode;
ret = -get_errno();
goto errout;
}
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
ret = EPERM;
/* The errno value has already been set */
goto errout_with_fd;
}
/* Perform the driver open operation. NOTE that the open method may be
* called many times. The driver/mountpoint logic should handled this
* because it may also be closed that many times.
*/
ret = OK;
filep->f_path = fullpath; /* The mem will free in close(fd); */
filep->f_relpath = relpath;
acc_mode = oflag_convert_mode(oflags);
if (inode->u.i_ops->open)
{
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode))
{
if (VfsPermissionCheck(inode->i_uid, inode->i_gid, inode->i_mode, EXEC_OP))
{
ret = EACCES;
goto errout_with_fd;
}
ret = inode->u.i_mops->open(filep, relpath, oflags, mode);
}
else
#endif
{
if (VfsPermissionCheck(inode->i_uid, inode->i_gid, inode->i_mode, acc_mode))
{
ret = EACCES;
goto errout_with_fd;
}
ret = inode->u.i_ops->open(filep);
}
}
if (ret < 0)
{
ret = -ret;
goto errout_with_fd;
}
/* we do not bother to handle the NULL scenario, if so, page-cache feature will not be used
* when we do the file fault */
add_mapping(filep, fullpath);
return fd;
errout_with_fd:
files_release(fd);
errout_with_inode:
inode_release(inode);
free(fullpath);
errout:
set_errno(ret);
if (fullpath)
{
free(fullpath);
}
set_errno(-ret);
return VFS_ERROR;
}
@@ -320,43 +367,36 @@ errout:
int open(const char *path, int oflags, ...)
{
mode_t mode = 0666; /* File read-write properties. */
mode_t mode = DEFAULT_FILE_MODE; /* File read-write properties. */
#ifdef LOSCFG_FILE_MODE
va_list ap;
va_start(ap, oflags);
mode = va_arg(ap, int);
va_end(ap);
if ((oflags & (O_WRONLY | O_CREAT)) != 0)
{
mode &= ~GetUmask();
mode &= (S_IRWXU|S_IRWXG|S_IRWXO);
}
#endif
return do_open(AT_FDCWD, path, oflags, mode);
}
int open64 (const char *__path, int __oflag, ...)
{
mode_t mode = 0666; /* File read-write properties. */
mode_t mode = DEFAULT_FILE_MODE; /* File read-write properties. */
#ifdef LOSCFG_FILE_MODE
va_list ap;
va_start(ap, __oflag);
mode = va_arg(ap, int);
va_end(ap);
if ((__oflag & (O_WRONLY | O_CREAT)) != 0)
{
mode &= ~GetUmask();
mode &= (S_IRWXU|S_IRWXG|S_IRWXO);
}
#endif
return open (__path, ((unsigned int)__oflag) | O_LARGEFILE, mode);
}
/****************************************************************************
* Name: openat
*
* Description: open by dirfd
*
****************************************************************************/
int openat(int dirfd, const char * path, int oflags, ...)
{
mode_t mode = 0666; /* File read-write properties. */
#ifdef LOSCFG_FILE_MODE
va_list ap;
va_start(ap, oflags);
mode = va_arg(ap, int);
va_end(ap);
#endif
return do_open(dirfd, path, oflags, mode);
}
Executable → Regular
+3 -6
View File
@@ -45,7 +45,7 @@
#include "errno.h"
#include "debug.h"
#include "fs/fs.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "stdlib.h"
#include "stdio.h"
#include "console.h"
@@ -226,14 +226,11 @@ static int wait_sem_time(poll_wait_head wait, const struct timespec *time_ptr)
static int file_poll(struct file *filep, poll_table *wait)
{
struct inode *inode = NULL;
int ret = -ENOSYS;
inode = filep->f_inode;
if (inode != NULL && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL)
if (filep->ops != NULL && filep->ops->poll != NULL)
{
ret = inode->u.i_ops->poll(filep, wait);
ret = filep->ops->poll(filep, wait);
}
return ret;
Executable → Regular
+7 -12
View File
@@ -48,7 +48,7 @@
#include "assert.h"
#include "errno.h"
#include "user_copy.h"
#include "inode/inode.h"
#include "fs/vnode.h"
/****************************************************************************
* Public Functions
@@ -77,14 +77,10 @@
*
****************************************************************************/
ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes)
ssize_t file_read(struct file *filep, void *buf, size_t nbytes)
{
FAR struct inode *inode = NULL;
int ret = -EBADF;
DEBUGASSERT(filep);
inode = filep->f_inode;
if (buf == NULL)
{
ret = -EFAULT;
@@ -103,14 +99,14 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes)
* method?
*/
else if (inode && inode->u.i_ops && inode->u.i_ops->read)
else if (filep->ops && filep->ops->read)
{
/* Yes.. then let it perform the read. NOTE that for the case of the
* mountpoint, we depend on the read methods being identical in
* signature and position in the operations vtable.
*/
ret = (int)inode->u.i_ops->read(filep, (char *)buf, (size_t)nbytes);
ret = (int)filep->ops->read(filep, (char *)buf, (size_t)nbytes);
}
/* If an error occurred, set errno and return -1 (ERROR) */
@@ -143,12 +139,12 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes)
*
****************************************************************************/
ssize_t read(int fd, FAR void *buf, size_t nbytes)
ssize_t read(int fd, void *buf, size_t nbytes)
{
/* Did we get a valid file descriptor? */
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct file *filep = NULL;
struct file *filep = NULL;
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
#endif
@@ -158,7 +154,7 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes)
*/
#if defined(LOSCFG_NET_LWIP_SACK)
FAR void *bufbak = buf;
void *bufbak = buf;
ssize_t ret;
if (LOS_IsUserAddress((VADDR_T)(uintptr_t)buf))
{
@@ -208,7 +204,6 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes)
}
}
/* The descriptor is in a valid range to file descriptor... do the
* read. First, get the file structure.
*/
Executable → Regular
+155 -213
View File
@@ -40,253 +40,197 @@
#include "vfs_config.h"
#include "stdio.h"
#include "unistd.h"
#include "errno.h"
#include "fs/fs.h"
#include "stdlib.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "fs_other.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_RENAME
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_RENAME 1
#endif
#ifdef FS_HAVE_RENAME
#include "limits.h"
#include "fs/fs_operation.h"
/****************************************************************************
* Public Functions
****************************************************************************/
int do_rename(int oldfd, FAR const char *oldpath, int newfd, FAR const char *newpath)
static int check_rename_target(struct Vnode *old_vnode, struct Vnode *old_parent_vnode,
struct Vnode *new_vnode, struct Vnode *new_parent_vnode)
{
FAR struct inode *oldinode;
FAR struct inode *newinode;
const char *oldrelpath = NULL;
char *fulloldpath = NULL;
char *fulloldpath_bak = NULL;
char *fullnewpath = NULL;
char *fullnewpath_bak = NULL;
#ifndef CONFIG_DISABLE_MOUNTPOINT
const char *newrelpath = NULL;
#endif
int errcode = ENOERR;
int ret;
struct inode_search_s old_desc, new_desc;
/* Ignore paths that are interpreted as the root directory which has no name
* and cannot be moved
*/
if (!oldpath || *oldpath == '\0' ||
!newpath || *newpath == '\0')
if (old_vnode == NULL || old_parent_vnode == NULL ||
new_parent_vnode == NULL || new_parent_vnode->type != VNODE_TYPE_DIR)
{
errcode = EINVAL;
return -ENOENT;
}
if (old_vnode->type != VNODE_TYPE_DIR && old_vnode->type != VNODE_TYPE_REG)
{
return -EACCES;
}
if (new_vnode != NULL && new_vnode->type != old_vnode->type)
{
if (new_vnode->type == VNODE_TYPE_DIR)
{
return -EISDIR;
}
return -ENOTDIR;
}
if (new_vnode != NULL && new_vnode->useCount != 0)
{
return -EBUSY;
}
if (VfsVnodePermissionCheck(old_parent_vnode, WRITE_OP)
|| VfsVnodePermissionCheck(new_parent_vnode, WRITE_OP))
{
return -EACCES;
}
if (old_parent_vnode->originMount != new_parent_vnode->originMount)
{
return -EXDEV;
}
if ((old_vnode->flag & VNODE_FLAG_MOUNT_NEW)
|| (old_vnode->flag & VNODE_FLAG_MOUNT_ORIGIN))
{
return -EBUSY;
}
if (new_vnode != NULL && ((new_vnode->flag & VNODE_FLAG_MOUNT_NEW)
|| (new_vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)))
{
return -EBUSY;
}
return OK;
}
static int check_path_invalid(const char *fulloldpath, const char *fullnewpath)
{
char cwd[PATH_MAX];
char *pret = getcwd(cwd, PATH_MAX);
ssize_t len = strlen(fulloldpath);
if (pret != NULL)
{
if (!strcmp(fulloldpath, cwd))
{
return -EBUSY;
}
}
if (strncmp(fulloldpath, fullnewpath, len))
{
return OK;
}
if (fullnewpath[len] != '/')
{
return OK;
}
return -EINVAL;
}
int do_rename(int oldfd, const char *oldpath, int newfd, const char *newpath)
{
struct Vnode *old_parent_vnode = NULL;
struct Vnode *new_parent_vnode = NULL;
struct Vnode *old_vnode = NULL;
struct Vnode *new_vnode = NULL;
char *fulloldpath = NULL;
char *fullnewpath = NULL;
char *oldname = NULL;
char *newname = NULL;
int ret;
if (!oldpath || *oldpath == '\0' || !newpath || *newpath == '\0')
{
ret = -EINVAL;
goto errout;
}
ret = vfs_normalize_pathat(oldfd, oldpath, &fulloldpath);
if (ret < 0)
{
errcode = -ret;
goto errout;
}
fulloldpath_bak = fulloldpath;
{
goto errout;
}
ret = vfs_normalize_pathat(newfd, newpath, &fullnewpath);
if (ret < 0)
{
errcode = -ret;
goto errout_with_path;
}
fullnewpath_bak = fullnewpath;
{
goto errout_with_oldpath;
}
oldname = strrchr(fulloldpath, '/') + 1;
newname = strrchr(fullnewpath, '/') + 1;
ret = check_path_invalid(fulloldpath, fullnewpath);
if (ret != OK)
{
goto errout_with_newpath;
}
/* Get an inode that includes the oldpath */
SETUP_SEARCH(&old_desc, fulloldpath, false);
ret = inode_find(&old_desc);
VnodeHold();
ret = VnodeLookup(fulloldpath, &old_vnode, 0);
if (ret < 0)
{
errcode = EACCES;
free(fullnewpath_bak);
goto errout_with_path;
goto errout_with_vnode;
}
oldinode = old_desc.node;
oldrelpath = old_desc.relpath;
#ifndef CONFIG_DISABLE_MOUNTPOINT
/* Verify that the old inode is a valid mountpoint. */
if (INODE_IS_MOUNTPT(oldinode) && oldinode->u.i_mops)
old_parent_vnode = old_vnode->parent;
ret = VnodeLookup(fullnewpath, &new_vnode, 0);
if (ret == OK)
{
/* Get an inode for the new relpath -- it should like on the same
* mountpoint
*/
SETUP_SEARCH(&new_desc, fullnewpath, false);
ret = inode_find(&new_desc);
if (ret < 0)
{
errcode = EACCES;
goto errout_with_oldinode;
}
newinode = new_desc.node;
newrelpath = new_desc.relpath;
/* Verify that the two paths lie on the same mountpoint inode */
if (oldinode != newinode)
{
errcode = EXDEV;
goto errout_with_newinode;
}
/* Perform the rename operation using the relative paths
* at the common mountpoint.
*/
if (oldinode->u.i_mops->rename)
{
ret = oldinode->u.i_mops->rename(oldinode, oldrelpath, newrelpath);
if (ret < 0)
{
errcode = -ret;
goto errout_with_newinode;
}
}
else
{
errcode = ENOSYS;
goto errout_with_newinode;
}
/* Successfully renamed */
inode_release(newinode);
new_parent_vnode = new_vnode->parent;
}
else
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
{
/* Create a new, empty inode at the destination location */
if (VfsPermissionCheck(old_desc.parent->i_uid, old_desc.parent->i_gid,
old_desc.parent->i_mode, EXEC_OP | WRITE_OP))
{
ret = EACCES;
goto errout_with_oldinode;
}
SETUP_SEARCH(&new_desc, fullnewpath, false);
ret = inode_find(&new_desc);
if (ret < 0)
{
errcode = EACCES;
goto errout_with_oldinode;
}
newinode = new_desc.node;
newrelpath = new_desc.relpath;
if (VfsPermissionCheck(new_desc.parent->i_uid, new_desc.parent->i_gid,
new_desc.parent->i_mode, EXEC_OP | WRITE_OP))
{
ret = EACCES;
goto errout_with_oldinode;
}
inode_semtake();
ret = inode_reserve(fullnewpath, &newinode);
if (ret < 0)
{
/* It is an error if a node at newpath already exists in the tree
* OR if we fail to allocate memory for the new inode (and possibly
* any new intermediate path segments).
*/
inode_semgive();
errcode = EEXIST;
goto errout_with_oldinode;
}
/* Copy the inode state from the old inode to the newly allocated inode */
newinode->i_child = oldinode->i_child; /* Link to lower level inode */
newinode->i_flags = oldinode->i_flags; /* Flags for inode */
newinode->u.i_ops = oldinode->u.i_ops; /* Inode operations */
#ifdef LOSCFG_FILE_MODE
newinode->i_mode = oldinode->i_mode; /* Access mode flags */
#endif
newinode->i_private = oldinode->i_private; /* Per inode driver private data */
/* We now have two copies of the inode. One with a reference count of
* zero (the new one), and one that may have multiple references
* including one by this logic (the old one)
*
* Remove the old inode. Because we hold a reference count on the
* inode, it will not be deleted now. It will be deleted when all of
* the references to to the inode have been released (perhaps when
* inode_release() is called below). inode_remove() should return
* -EBUSY to indicate that the inode was not deleted now.
*/
ret = inode_remove(fulloldpath);
if (ret < 0 && ret != -EBUSY)
{
/* Remove the new node we just recreated */
(void)inode_remove(fullnewpath);
inode_semgive();
errcode = -ret;
goto errout_with_oldinode;
}
/* Remove all of the children from the unlinked inode */
oldinode->i_child = NULL;
inode_semgive();
new_parent_vnode = new_vnode;
new_vnode = NULL;
}
#else
ret = check_rename_target(old_vnode, old_parent_vnode, new_vnode, new_parent_vnode);
if (ret != OK)
{
errcode = ENXIO;
goto errout_with_oldinode;
goto errout_with_vnode;
}
#endif
/* rename file page cache mapping if necessary */
if (old_vnode == new_vnode)
{
VnodeDrop();
free(fulloldpath);
free(fullnewpath);
return OK;
}
if (!old_vnode->vop || !old_vnode->vop->Rename)
{
ret = -ENOSYS;
goto errout_with_vnode;
}
ret = old_vnode->vop->Rename(old_vnode, new_parent_vnode, oldname, newname);
if (ret < 0)
{
goto errout_with_vnode;
}
VnodeFree(new_vnode);
VnodePathCacheFree(old_vnode);
PathCacheAlloc(new_parent_vnode, old_vnode, newname, strlen(newname));
VnodeDrop();
ret = update_file_path(fulloldpath, fullnewpath);
if (ret != OK)
{
PRINT_ERR("rename change file path failed, something bad might happped.\n");
}
/* Successfully renamed */
rename_mapping(fulloldpath, fullnewpath);
/* Successfully renamed */
inode_release(oldinode);
free(fulloldpath_bak);
free(fullnewpath_bak);
free(fulloldpath);
free(fullnewpath);
return OK;
#ifndef CONFIG_DISABLE_MOUNTPOINT
errout_with_newinode:
inode_release(newinode);
#endif
errout_with_oldinode:
inode_release(oldinode);
free(fullnewpath_bak);
errout_with_path:
free(fulloldpath_bak);
errout_with_vnode:
VnodeDrop();
errout_with_newpath:
free(fullnewpath);
errout_with_oldpath:
free(fulloldpath);
errout:
set_errno(errcode);
set_errno(-ret);
return VFS_ERROR;
}
/****************************************************************************
* Name: rename
*
@@ -294,7 +238,7 @@ errout:
*
****************************************************************************/
int rename(FAR const char *oldpath, FAR const char *newpath)
int rename(const char *oldpath, const char *newpath)
{
return do_rename(AT_FDCWD, oldpath, AT_FDCWD, newpath);
}
@@ -306,9 +250,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
*
****************************************************************************/
int renameat(int oldfd, FAR const char *oldpath, int newdfd, FAR const char *newpath)
int renameat(int oldfd, const char *oldpath, int newdfd, const char *newpath)
{
return do_rename(oldfd, oldpath, newdfd, newpath);
}
#endif /* FS_HAVE_RENAME */
Executable → Regular
+93 -126
View File
@@ -43,32 +43,50 @@
#include "errno.h"
#include "fs/fs.h"
#include "stdlib.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "sys/stat.h"
#include "string.h"
#include "fs_other.h"
#include "limits.h"
/****************************************************************************
* Pre-processor Definitions
* Private Functions
****************************************************************************/
static int check_target(struct Vnode *vnode, char *name) {
if (vnode == NULL)
{
return -ENOENT;
}
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
if (vnode->type != VNODE_TYPE_DIR)
{
return -ENOTDIR;
}
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
if (vnode->useCount > 0)
{
return -EBUSY;
}
#undef FS_HAVE_RMDIR
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_RMDIR 1
#endif
#ifdef FS_HAVE_RMDIR
if ((vnode->flag & VNODE_FLAG_MOUNT_NEW)
|| (vnode->flag & VNODE_FLAG_MOUNT_ORIGIN))
{
return -EBUSY;
}
char cwd[PATH_MAX];
char *pret = getcwd(cwd, PATH_MAX);
if (pret != NULL)
{
struct Vnode *cwdnode = NULL;
int ret = VnodeLookup(cwd, &cwdnode, 0);
if (ret == OK && (cwdnode == vnode))
{
return -EBUSY;
}
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -80,143 +98,94 @@
*
****************************************************************************/
int do_rmdir(int dirfd, FAR const char *pathname)
int do_rmdir(int dirfd, const char *pathname)
{
FAR struct inode *inode;
const char *relpath = NULL;
int errcode;
struct Vnode *vnode = NULL;
char *fullpath = NULL;
char *relativepath = NULL;
char *name = NULL;
int ret;
struct inode_search_s desc;
/* Get relative path by dirfd*/
ret = get_path_from_fd(dirfd, &relativepath);
if (ret < 0)
{
errcode = ret;
goto errout;
}
ret = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
if (relativepath)
{
ret = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
free(relativepath);
}
if (ret < 0)
{
errcode = -ret;
goto errout;
}
/* Get an inode for this file. inode_find() automatically increments the
* reference count on the inode if one is found.
*/
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
{
free(fullpath);
errcode = EACCES;
goto errout;
}
inode = desc.node;
relpath = desc.relpath;
#ifndef CONFIG_DISABLE_MOUNTPOINT
/* Check if the inode is a valid mountpoint. */
if (INODE_IS_MOUNTPT(inode) && inode->u.i_mops)
{
/* Perform the rmdir operation using the relative path
* from the mountpoint.
*/
if (inode->u.i_mops->rmdir)
if (ret < 0)
{
if (!strlen(relpath))
{
errcode = EPERM;
goto errout_with_inode;
}
goto errout;
}
ret = inode->u.i_mops->rmdir(inode, relpath);
if (ret < 0)
{
errcode = -ret;
goto errout_with_inode;
}
name = strrchr(fullpath, '/');
VnodeHold();
ret = VnodeLookup(fullpath, &vnode, 0);
}
else
{
name = strrchr(pathname, '/');
VnodeHold();
if (name == NULL)
{
name = (char *)pathname;
}
else
{
errcode = ENOSYS;
goto errout_with_inode;
name++;
}
ret = VnodeLookup(pathname, &vnode, 0);
}
else
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* If this is a "dangling" pseudo-directory node (i.e., it has no
* operations) then rmdir should remove the node.
*/
if (!inode->u.i_ops)
if (ret != OK)
{
/* If the directory inode has children, however, then it cannot be
* removed.
*/
if (inode->i_child)
{
errcode = ENOTEMPTY;
goto errout_with_inode;
}
/* Remove the inode. NOTE: Because we hold a reference count on the
* inode, it will not be deleted now. But probably when inode_release()
* is called below. inode_remove should return -EBUSY to indicate that
* the inode was not deleted now.
*/
if (VfsPermissionCheck(desc.parent->i_uid, desc.parent->i_gid, desc.parent->i_mode, EXEC_OP | WRITE_OP))
{
errcode = EACCES;
goto errout_with_inode;
}
inode_semtake();
ret = inode_remove(fullpath);
inode_semgive();
if (ret < 0 && ret != -EBUSY)
{
errcode = -ret;
goto errout_with_inode;
}
goto errout_with_lock;
}
else
ret = check_target(vnode, name);
if (ret != OK) {
PRINT_ERR("rmdir failed err = %d\n", ret);
goto errout_with_lock;
}
if (VfsVnodePermissionCheck(vnode->parent, WRITE_OP)) {
ret = -EACCES;
goto errout_with_lock;
}
if (vnode && vnode->vop && vnode->vop->Rmdir) {
ret = vnode->vop->Rmdir(vnode->parent, vnode, name);
} else {
ret = -ENOSYS;
}
if (ret < 0) {
goto errout_with_lock;
}
VnodeFree(vnode);
VnodeDrop();
/* Successfully unlinked */
if (fullpath)
{
errcode = ENOTDIR;
goto errout_with_inode;
free(fullpath);
}
#else
{
errcode = ENXIO;
goto errout_with_inode;
}
#endif
/* Successfully removed the directory */
inode_release(inode);
free(fullpath);
return OK;
errout_with_inode:
inode_release(inode);
free(fullpath);
errout_with_lock:
VnodeDrop();
errout:
set_errno(errcode);
if (fullpath)
{
free(fullpath);
}
set_errno(-ret);
return VFS_ERROR;
}
@@ -227,9 +196,7 @@ errout:
*
****************************************************************************/
int rmdir(FAR const char *pathname)
int rmdir(const char *pathname)
{
return do_rmdir(AT_FDCWD, pathname);
}
#endif /* FS_HAVE_RMDIR */
Executable → Regular
-1
View File
@@ -54,7 +54,6 @@
#include "los_signal.h"
#include "los_syscall.h"
#include "inode/inode.h"
#ifndef CONFIG_DISABLE_POLL
Executable → Regular
+23 -170
View File
@@ -43,99 +43,8 @@
#include "sys/stat.h"
#include "string.h"
#include "stdlib.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "fs_other.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: statpseudo
****************************************************************************/
static inline int statpseudo(FAR struct inode *inode, FAR struct stat *buf)
{
/* Most of the stat entries just do not apply */
(void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
buf->st_mode |= inode->i_mode;
buf->st_uid = inode->i_uid;
buf->st_gid = inode->i_gid;
if (INODE_IS_SPECIAL(inode))
{
#if defined(CONFIG_FS_NAMED_SEMAPHORES)
if (INODE_IS_NAMEDSEM(inode))
{
buf->st_mode = S_IFSEM;
}
else
#endif
#if !defined(CONFIG_DISABLE_MQUEUE)
if (INODE_IS_MQUEUE(inode))
{
buf->st_mode = S_IFMQ;
}
else
#endif
#if defined(CONFIG_FS_SHM)
if (INODE_IS_SHM(inode))
{
buf->st_mode = S_IFSHM;
}
else
#endif
{
}
}
else if (inode->u.i_ops)
{
/* Determine the type of the inode */
if (INODE_IS_MOUNTPT(inode))
{
buf->st_mode |= S_IFDIR;
}
else if (INODE_IS_BLOCK(inode))
{
/* What is if also has child inodes? */
buf->st_mode |= S_IFBLK;
}
else /* if (INODE_IS_DRIVER(inode)) */
{
/* What is it if it also has child inodes? */
buf->st_mode |= S_IFCHR;
}
}
else
{
/* If it has no operations, then it must just be a intermediate
* node in the inode tree. It is something like a directory.
* We'll say that all pseudo-directories are read-able but not
* write-able.
*/
buf->st_mode |= S_IFDIR | inode->i_mode;
}
return OK;
}
/****************************************************************************
* Name: statroot
****************************************************************************/
static inline int statroot(FAR struct stat *buf)
{
/* There is no inode associated with the fake root directory */
(void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
return OK;
}
/****************************************************************************
* Global Functions
****************************************************************************/
@@ -156,120 +65,64 @@ static inline int statroot(FAR struct stat *buf)
*
****************************************************************************/
int stat(FAR const char *path, FAR struct stat *buf)
int stat(const char *path, struct stat *buf)
{
FAR struct inode *inode;
const char *relpath = NULL;
int ret = OK;
char *fullpath = NULL;
struct inode_search_s desc;
struct Vnode *vp = NULL;
int ret;
/* Sanity checks */
if (!path || !buf)
{
ret = EFAULT;
ret = -EFAULT;
goto errout;
}
if (!path[0])
{
ret = ENOENT;
ret = -ENOENT;
goto errout;
}
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
/* Get an vnode for this file */
VnodeHold();
ret = VnodeLookup(path, &vp, 0);
if (ret < 0)
{
ret = -ret;
VnodeDrop();
goto errout;
}
/* Check for the fake root directory (which has no inode) */
if (strcmp(fullpath, "/") == 0)
{
free(fullpath);
return statroot(buf);
}
/* Get an inode for this file */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
{
ret = EACCES;
goto errout_with_path;
}
inode = desc.node;
relpath = desc.relpath;
/* The way we handle the stat depends on the type of inode that we
/* The way we handle the stat depends on the type of vnode that we
* are dealing with.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode))
if (vp->vop != NULL && vp->vop->Getattr != NULL)
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the stat() method
*/
if (inode->u.i_mops && inode->u.i_mops->stat)
{
/* Perform the stat() operation */
ret = inode->u.i_mops->stat(inode, relpath, buf);
}
else
{
ret = ENOSYS;
}
vp->useCount++;
VnodeDrop();
ret = vp->vop->Getattr(vp, buf);
VnodeHold();
vp->useCount--;
VnodeDrop();
}
else
#endif
{
if (strlen(relpath) > 0)
{
ret = ENOENT;
goto errout_with_inode;
}
/* The node is part of the root pseudo file system */
if (VfsPermissionCheck(desc.parent->i_uid, desc.parent->i_gid, desc.parent->i_mode, EXEC_OP))
{
ret = EACCES;
goto errout_with_inode;
}
ret = statpseudo(inode, buf);
VnodeDrop();
ret = -ENOSYS;
goto errout;
}
/* Check if the stat operation was successful */
if (ret < 0)
{
ret = -ret;
goto errout_with_inode;
goto errout;
}
/* Successfully stat'ed the file */
inode_release(inode);
free(fullpath);
return OK;
/* Failure conditions always set the errno appropriately */
errout_with_inode:
inode_release(inode);
errout_with_path:
free(fullpath);
errout:
set_errno(ret);
set_errno(-ret);
return VFS_ERROR;
}
int isatty(int fd)
{
return 0;
}
Executable → Regular
+28 -93
View File
@@ -42,23 +42,9 @@
#include "sys/statfs.h"
#include "string.h"
#include "sched.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "errno.h"
#include "stdlib.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: statpseudo
****************************************************************************/
static inline int statpseudofs(FAR struct inode *inode, FAR struct statfs *buf)
{
(void)memset_s(buf, sizeof(struct statfs), 0, sizeof(struct statfs));
return OK;
}
/****************************************************************************
* Public Functions
@@ -81,113 +67,62 @@ static inline int statpseudofs(FAR struct inode *inode, FAR struct statfs *buf)
*
****************************************************************************/
int statfs(FAR const char *path, FAR struct statfs *buf)
int statfs(const char *path, struct statfs *buf)
{
FAR struct inode *inode;
int ret = OK;
char *fullpath = NULL;
struct inode_search_s desc;
struct Vnode *vnode = NULL;
struct Mount *mnt = NULL;
int ret = OK;
/* Sanity checks */
if (!path || !buf)
{
ret = EFAULT;
ret = -EFAULT;
goto errout;
}
if (!path[0])
{
ret = ENOENT;
ret = -ENOENT;
goto errout;
}
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
/* Get an vnode for this file */
VnodeHold();
ret = VnodeLookup(path, &vnode, 0);
if (ret < 0)
{
ret = -ret;
VnodeDrop();
goto errout;
}
vnode->useCount++;
VnodeDrop();
/* Get an inode for this file */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
mnt = vnode->originMount;
if (mnt == NULL || mnt->ops == NULL || mnt->ops->Statfs == NULL)
{
ret = EACCES;
free(fullpath);
goto errout;
}
inode = desc.node;
/* The way we handle the statfs depends on the type of inode that we
* are dealing with.
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
if (INODE_IS_MOUNTPT(inode))
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the statfs() method
*/
if (inode->u.i_mops && inode->u.i_mops->stat && inode->u.i_mops->statfs)
{
struct stat *statbuf = LOS_MemAlloc(m_aucSysMem0, sizeof(struct stat));
if (statbuf == NULL)
{
ret = ENOMEM;
}
else
{
/* Check whether the path is available or not */
ret = inode->u.i_mops->stat(inode, desc.relpath, statbuf);
if (ret == 0)
{
/* Perform the statfs() operation */
(void)memset_s((void *)buf, sizeof(struct statfs), 0, sizeof(struct statfs));
ret = inode->u.i_mops->statfs(inode, buf);
}
(VOID)LOS_MemFree(m_aucSysMem0, statbuf);
}
}
ret = -ENOSYS;
goto errout_with_useCount;
}
else
#endif
{
/* The node is part of the root pseudo file system */
if (strlen(desc.relpath) > 0)
ret = mnt->ops->Statfs(mnt, buf);
if (ret < 0)
{
ret = ENOENT;
goto errout_with_inode;
goto errout_with_useCount;
}
ret = statpseudofs(inode, buf);
}
/* Check if the statfs operation was successful */
VnodeHold();
vnode->useCount--;
VnodeDrop();
if (ret < 0)
{
ret = -ret;
goto errout_with_inode;
}
/* Successfully statfs'ed the file */
inode_release(inode);
free(fullpath);
return OK;
/* Failure conditions always set the errno appropriately */
errout_with_inode:
inode_release(inode);
free(fullpath);
errout_with_useCount:
VnodeHold();
vnode->useCount--;
VnodeDrop();
errout:
set_errno(ret);
set_errno(-ret);
return VFS_ERROR;
}
Executable → Regular
+8 -8
View File
@@ -45,7 +45,7 @@
#include "assert.h"
#include "errno.h"
#include "inode/inode.h"
#include "fs/vnode.h"
/****************************************************************************
* Name: file_truncate
@@ -56,9 +56,9 @@
* the errno variable.
*
****************************************************************************/
static int file_truncate(FAR struct file *filep, off_t length)
static int file_truncate(struct file *filep, off_t length)
{
FAR struct inode *inode = NULL;
struct Vnode *vnode = NULL;
int ret;
int err;
@@ -70,13 +70,13 @@ static int file_truncate(FAR struct file *filep, off_t length)
goto errout;
}
/* Is this inode a registered mountpoint? Does it support the
/* Is this vnode a registered mountpoint? Does it support the
* truncate operations may be relevant to device drivers but only
* the mountpoint operations vtable contains a truncate method.
*/
inode = filep->f_inode;
if (!inode || !inode->u.i_mops || !inode->u.i_mops->truncate)
vnode = filep->f_vnode;
if (!vnode || !vnode->vop || !vnode->vop->Truncate)
{
err = EBADF;
goto errout;
@@ -86,7 +86,7 @@ static int file_truncate(FAR struct file *filep, off_t length)
* a write-able file system.
*/
ret = inode->u.i_mops->truncate(filep, length);
ret = vnode->vop->Truncate(vnode, length);
if (ret < 0)
{
err = -ret;
@@ -136,7 +136,7 @@ errout:
int ftruncate(int fd, off_t length)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct file *filep = NULL;
struct file *filep = NULL;
#endif
/* Did we get a valid file descriptor? */
Executable → Regular
+43 -63
View File
@@ -45,7 +45,7 @@
#include "assert.h"
#include "errno.h"
#include "inode/inode.h"
#include "fs/vnode.h"
/****************************************************************************
* Name: file_truncate
@@ -57,55 +57,53 @@
*
****************************************************************************/
static int file_truncate64(FAR struct file *filep, off64_t length)
static int file_truncate64(struct file *filep, off64_t length)
{
FAR struct inode *inode = NULL;
int ret;
int err;
/* Was this file opened for write access? */
if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY)
{
err = EACCES;
goto errout;
}
/* Is this inode a registered mountpoint? Does it support the
struct Vnode *vnode = NULL;
int err;
/* Was this file opened for write access? */
if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY)
{
err = -EACCES;
goto errout;
}
/* Is this vnode a registered mountpoint? Does it support the
* truncate operations may be relevant to device drivers but only
* the mountpoint operations vtable contains a truncate method.
*/
inode = filep->f_inode;
if (!inode || !inode->u.i_mops || !inode->u.i_mops->truncate64)
{
err = EBADF;
goto errout;
}
/* Does the file system support the truncate method? It should if it is
vnode = filep->f_vnode;
if (!vnode || !vnode->vop || !vnode->vop->Truncate64)
{
err = -ENOSYS;
goto errout;
}
/* Does the file system support the truncate method? It should if it is
* a write-able file system.
*/
ret = inode->u.i_mops->truncate64(filep, length);
if (ret < 0)
{
err = -ret;
goto errout;
}
return ret;
errout:
set_errno(err);
return VFS_ERROR;
}
/****************************************************************************
* Name: ftruncate
*
* Description:
* The ftruncate() function causes the regular file referenced by fd to
err = vnode->vop->Truncate64(vnode, length);
if (err < 0)
{
goto errout;
}
return OK;
errout:
set_errno(-err);
return VFS_ERROR;
}
/****************************************************************************
* Name: ftruncate
*
* Description:
* The ftruncate() function causes the regular file referenced by fd to
* have a size of length bytes.
*
* If the file previously was larger than length, the extra data is
@@ -137,7 +135,7 @@ errout:
int ftruncate64(int fd, off64_t length)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct file *filep = NULL;
struct file *filep = NULL;
#endif
/* Did we get a valid file descriptor? */
@@ -173,21 +171,3 @@ int ftruncate64(int fd, off64_t length)
return file_truncate64(filep, length);
#endif
}
int truncate64(const char *path, off64_t length)
{
int fd;
int ret;
fd = open(path, O_RDWR);
if (fd == VFS_ERROR)
{
/* The errno value has already been set */
return VFS_ERROR;
}
ret = ftruncate64(fd, length);
close(fd);
return ret;
}
Executable → Regular
+63 -161
View File
@@ -44,32 +44,31 @@
#include "fs/fs.h"
#include "fcntl.h"
#include "inode/inode.h"
#include "fs/vnode.h"
#include "stdlib.h"
#include "fs_other.h"
/****************************************************************************
* Pre-processor Definitions
* Private Functions
****************************************************************************/
static int check_target(struct Vnode *vnode)
{
if (vnode->type == VNODE_TYPE_DIR)
{
return -EISDIR;
}
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_UNLINK
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_UNLINK 1
#endif
#ifdef FS_HAVE_UNLINK
if (vnode->useCount > 0)
{
return -EBUSY;
}
if (VfsVnodePermissionCheck(vnode->parent, WRITE_OP))
{
return -EACCES;
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -81,177 +80,82 @@
*
****************************************************************************/
int do_unlink(int dirfd, FAR const char *pathname)
int do_unlink(int dirfd, const char *pathname)
{
FAR struct inode *inode;
const char *relpath = NULL;
int errcode;
int ret;
char *fullpath = NULL;
char *relativepath = NULL;
struct inode_search_s desc;
struct Vnode *vnode = NULL;
int ret;
char *name = NULL;
char *fullpath = NULL;
char *relativepath = NULL;
/* Get relative path by dirfd*/
ret = get_path_from_fd(dirfd, &relativepath);
if (ret < 0)
{
errcode = ret;
goto errout;
}
errcode = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
ret = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
if (relativepath)
{
free(relativepath);
}
if (errcode < 0)
{
errcode = -errcode;
goto errout;
}
/* Get an inode for this file */
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret < 0)
{
errcode = EACCES;
free(fullpath);
goto errout;
}
inode = desc.node;
relpath = desc.relpath;
#ifndef CONFIG_DISABLE_MOUNTPOINT
/* Check if the inode is a valid mountpoint. */
if (INODE_IS_MOUNTPT(inode) && inode->u.i_mops)
VnodeHold();
ret = VnodeLookup(fullpath, &vnode, 0);
if (ret < 0)
{
/* Perform the unlink operation using the relative path at the
* mountpoint.
*/
goto errout_with_lock;
}
if (inode->u.i_mops->unlink)
{
ret = inode->u.i_mops->unlink(inode, relpath);
if (ret < 0)
{
errcode = -ret;
goto errout_with_inode;
}
}
else
{
errcode = ENOSYS;
goto errout_with_inode;
}
ret = check_target(vnode);
if (ret < 0)
{
goto errout_with_lock;
}
name = strrchr(fullpath, '/') + 1;
if (vnode && vnode->vop && vnode->vop->Unlink)
{
ret = vnode->vop->Unlink(vnode->parent, vnode, name);
}
else if (vnode && vnode->fop && vnode->fop->unlink)
{
ret = vnode->fop->unlink(vnode);
}
else
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* If this is a "dangling" pseudo-file node (i.e., it has no operations)
* or a soft link, then rm should remove the node.
*/
if (!INODE_IS_SPECIAL(inode) && inode->u.i_ops)
{
/* If this is a pseudo-file node (i.e., it has no operations)
* then rmdir should remove the node.
*/
inode_semtake();
if (VfsPermissionCheck(desc.parent->i_uid, desc.parent->i_gid, desc.parent->i_mode, EXEC_OP | WRITE_OP))
{
errcode = EACCES;
goto errout_with_inode;
}
/* Refuse to unlink the inode if it has children. I.e., if it is
* functioning as a directory and the directory is not empty.
*/
if (inode->i_child != NULL)
{
errcode = ENOTEMPTY;
inode_semgive();
goto errout_with_inode;
}
/* Notify the driver that it has been unlinked. If there are no
* open references to the driver instance, then the driver should
* release all resources because it is no longer accessible.
*/
if (INODE_IS_DRIVER(inode) && inode->u.i_ops->unlink)
{
/* Notify the character driver that it has been unlinked */
ret = inode->u.i_ops->unlink(inode);
if (ret < 0)
{
errcode = -ret;
inode_semgive();
goto errout_with_inode;
}
}
#ifndef CONFIG_DISABLE_MOUNTPOINT
else if (INODE_IS_BLOCK(inode) && inode->u.i_bops->unlink)
{
/* Notify the block driver that it has been unlinked */
ret = inode->u.i_bops->unlink(inode);
if (ret < 0)
{
errcode = -ret;
inode_semgive();
goto errout_with_inode;
}
}
#endif
else
{
inode_semgive();
errcode = EACCES;
goto errout_with_inode;
}
inode_semgive();
}
else if (!INODE_IS_SPECIAL(inode) && (inode->u.i_ops == NULL))
{
/* It is a "dangling" pseudo-file node with no operations */
errcode = EISDIR;
goto errout_with_inode;
}
else
#endif
{
errcode = ENXIO;
goto errout_with_inode;
ret = -ENOSYS;
}
/* Thie file is being deleted, page-caches of the file will no longer be used,
* so drop all the page-caches for the file at this moment, and then remove mapping
* between the file and pagecache.
*/
(void)remove_mapping(fullpath, NULL);
if (ret != OK)
{
goto errout_with_lock;
}
VnodeFree(vnode);
VnodeDrop();
(void)remove_mapping(fullpath);
/* Successfully unlinked */
inode_release(inode);
free(fullpath);
return OK;
errout_with_inode:
inode_release(inode);
free(fullpath);
errout_with_lock:
VnodeDrop();
errout:
set_errno(errcode);
if (fullpath)
{
free(fullpath);
}
set_errno(-ret);
return VFS_ERROR;
}
@@ -262,7 +166,7 @@ errout:
*
****************************************************************************/
int unlink(FAR const char *pathname)
int unlink(const char *pathname)
{
return do_unlink(AT_FDCWD, pathname);
}
@@ -273,9 +177,9 @@ int unlink(FAR const char *pathname)
* Description: Remove a file managed a mountpoint by dirfd
*
****************************************************************************/
extern int do_rmdir(int dirfd, FAR const char *pathname);
extern int do_rmdir(int dirfd, const char *pathname);
int unlinkat(int dirfd, FAR const char *pathname, int flag)
int unlinkat(int dirfd, const char *pathname, int flag)
{
/* Now flag only support 0 && AT_REMOVEDIR */
if ((flag & ~AT_REMOVEDIR) != 0)
@@ -286,5 +190,3 @@ int unlinkat(int dirfd, FAR const char *pathname, int flag)
return do_unlink(dirfd, pathname);
}
#endif /* FS_HAVE_UNLINK */
Executable → Regular
+8 -11
View File
@@ -48,7 +48,7 @@
#include "sys/socket.h"
#include "console.h"
#include "user_copy.h"
#include "inode/inode.h"
#include "fs/vnode.h"
/****************************************************************************
* Public Functions
@@ -79,10 +79,8 @@
* values).
*
****************************************************************************/
ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
ssize_t file_write(struct file *filep, const void *buf, size_t nbytes)
{
FAR struct inode *inode;
int ret;
int err;
@@ -102,8 +100,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
/* Is a driver registered? Does it support the write method? */
inode = filep->f_inode;
if (!inode || !inode->u.i_ops || !inode->u.i_ops->write)
if (!filep->ops || !filep->ops->write)
{
err = EBADF;
goto errout;
@@ -111,7 +108,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
/* Yes, then let the driver perform the write */
ret = inode->u.i_ops->write(filep, (const char *)buf, nbytes);
ret = filep->ops->write(filep, (const char *)buf, nbytes);
if (ret < 0)
{
err = -ret;
@@ -161,7 +158,7 @@ errout:
* specified in buf, the value specified in count, or the current
* file offset is not suitably aligned.
* EIO
* A low-level I/O error occurred while modifying the inode.
* A low-level I/O error occurred while modifying the vnode.
* ENOSPC
* The device containing the file referred to by fd has no room for
* the data.
@@ -173,10 +170,10 @@ errout:
*
****************************************************************************/
ssize_t write(int fd, FAR const void *buf, size_t nbytes)
ssize_t write(int fd, const void *buf, size_t nbytes)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct file *filep;
struct file *filep;
#endif
/* Did we get a valid file descriptor? */
@@ -188,7 +185,7 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes)
/* Write to a socket descriptor is equivalent to send with flags == 0 */
#if defined(LOSCFG_NET_LWIP_SACK)
FAR const void *bufbak = buf;
const void *bufbak = buf;
ssize_t ret;
if (LOS_IsUserAddress((VADDR_T)(uintptr_t)buf))
{
Executable → Regular
+17 -14
View File
@@ -46,7 +46,6 @@
#include "sys/types.h"
#include "stdint.h"
#include "dirent.h"
#include "fs/fs.h"
#ifdef __cplusplus
@@ -132,7 +131,7 @@ struct fs_cromfsdir_s
struct tmpfs_directory_s; /* Forward reference */
struct fs_tmpfsdir_s
{
FAR struct tmpfs_directory_s *tf_tdo; /* Directory being enumerated */
struct tmpfs_directory_s *tf_tdo; /* Directory being enumerated */
unsigned int tf_index; /* Directory index */
};
@@ -147,12 +146,12 @@ struct fs_binfsdir_s
#ifdef CONFIG_FS_NXFFS
/* NXFFS is the tiny NuttX wear-leveling FLASH file system. The state value is
* the offset in FLASH memory to the next inode entry.
* the offset in FLASH memory to the next vnode entry.
*/
struct fs_nxffsdir_s
{
off_t nx_offset; /* Offset to the next inode */
off_t nx_offset; /* Offset to the next vnode */
};
#endif
@@ -203,8 +202,8 @@ struct fs_unionfsdir_s
uint8_t fu_ndx; /* Index of file system being enumerated */
bool fu_eod; /* True: At end of directory */
bool fu_prefix[2]; /* True: Fake directory in prefix */
FAR char *fu_relpath; /* Path being enumerated */
FAR struct fs_dirent_s *fu_lower[2]; /* dirent struct used by contained file system */
char *fu_relpath; /* Path being enumerated */
struct fs_dirent_s *fu_lower[2]; /* dirent struct used by contained file system */
};
#endif
@@ -215,7 +214,7 @@ struct fs_unionfsdir_s
struct fs_userfsdir_s
{
FAR void *fs_dir; /* Opaque pointer to UserFS DIR */
void *fs_dir; /* Opaque pointer to UserFS DIR */
};
#endif
@@ -226,21 +225,21 @@ struct fs_userfsdir_s
struct fs_hostfsdir_s
{
FAR void *fs_dir; /* Opaque pointer to host DIR */
void *fs_dir; /* Opaque pointer to host DIR */
};
#endif
struct fs_dirent_s
{
/* This is the node that was opened by opendir. The type of the inode
/* This is the node that was opened by opendir. The type of the vnode
* determines the way that the readdir() operations are performed. For the
* pseudo root pseudo-file system, it is also used to support rewind.
*
* We hold a reference on this inode so we know that it will persist until
* closedir() is called (although inodes linked to this inode may change).
* We hold a reference on this vnode so we know that it will persist until
* closedir() is called (although vnodes linked to this vnode may change).
*/
struct inode *fd_root;
struct Vnode *fd_root;
/* At present, only mountpoints require special handling flags */
@@ -252,6 +251,10 @@ struct fs_dirent_s
off_t fd_position;
/* This keeps track of the internal offset for some FSs */
off_t fd_int_offset;
/* Retained control information depends on the type of file system that
* provides is provides the mountpoint. Ideally this information should
* be hidden behind an opaque, file-system-dependent void *, but we put
@@ -282,7 +285,7 @@ struct fs_dirent_s
struct fs_binfsdir_s binfs;
#endif
#ifdef CONFIG_FS_PROCFS
FAR void *procfs;
void *procfs;
#endif
#ifdef CONFIG_FS_NXFFS
struct fs_nxffsdir_s nxffs;
@@ -297,7 +300,7 @@ struct fs_dirent_s
struct fs_spiffsdir_s spiffs;
#endif
#ifdef CONFIG_FS_LITTLEFS
FAR void *littlefs;
void *littlefs;
#endif
#ifdef CONFIG_FS_UNIONFS
struct fs_unionfsdir_s unionfs;
Executable → Regular
+8 -38
View File
@@ -67,9 +67,9 @@ extern "C" {
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct statfs; /* Forward reference */
typedef int (*foreach_mountpoint_t)(FAR const char *mountpoint,
FAR struct statfs *statbuf,
FAR void *arg);
typedef int (*foreach_mountpoint_t)(const char *mountpoint,
struct statfs *statbuf,
void *arg);
#endif
struct filelist *sched_getfiles(void);
@@ -110,6 +110,8 @@ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count);
*/
extern int get_path_from_fd(int fd, char **path);
extern int get_path_from_dirfd(int fd, char **path);
bool get_bit(int i);
/****************************************************************************
* Name: foreach_mountpoint
@@ -119,8 +121,8 @@ extern int get_path_from_fd(int fd, char **path);
* terminated when the callback 'handler' returns a non-zero value, or when
* all of the mountpoints have been visited.
*
* This is just a front end "filter" to foreach_inode() that forwards only
* mountpoint inodes. It is intended to support the mount() command to
* This is just a front end "filter" to foreach_vnode() that forwards only
* mountpoint vnodes. It is intended to support the mount() command to
* when the mount command is used to enumerate mounts.
*
* NOTE 1: Use with caution... The pseudo-file system is locked throughout
@@ -136,39 +138,7 @@ extern int get_path_from_fd(int fd, char **path);
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg);
#endif
/****************************************************************************
* Name: find_blockdriver
*
* Description:
* Return the inode of the block driver specified by 'pathname'
*
* Input Parameters:
* pathname - The full path to the block driver to be located
* mountflags - If MS_RDONLY is not set, then driver must support write
* operations (see include/sys/mount.h)
* ppinode - Address of the location to return the inode reference
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* EINVAL - Pathname or pinode is NULL.
* ENOENT - No block driver of this name is registered
* ENOTBLK - The inode associated with the pathname is not a block driver
* EACCESS - The MS_RDONLY option was not set but this driver does not
* support write access
*
* Attention:
* The parameter pathname is a full path, which begin with '/'.
* The parameter ppinode must point a valid memory, which size must be enough for storing struct inode.
*
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int find_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode);
int foreach_mountpoint(foreach_mountpoint_t handler, void *arg);
#endif
#ifdef __cplusplus
Executable → Regular
+271 -210
View File
@@ -58,6 +58,7 @@
#include "los_atomic.h"
#include "semaphore.h"
#include "los_spinlock.h"
#include "mount.h"
#ifndef CONFIG_DISABLE_MQUEUE
#include "mqueue.h"
@@ -158,8 +159,9 @@ extern "C" {
#define CHG_MTIME 32
#define CHG_CTIME 64
struct IATTR {
/* This structure is used for record inode attr. */
struct IATTR
{
/* This structure is used for record vnode attr. */
unsigned int attr_chg_valid;
unsigned int attr_chg_flags;
unsigned attr_chg_mode;
@@ -174,7 +176,7 @@ struct IATTR {
/* Forward references */
struct file;
struct inode;
struct Vnode;
struct stat;
struct statfs;
struct pollfd;
@@ -188,25 +190,30 @@ struct file_operations_vfs
{
/* The device driver open method differs from the mountpoint open method */
int (*open)(FAR struct file *filep);
int (*open)(struct file *filep);
/* The following methods must be identical in signature and position because
* the struct file_operations and struct mountp_operations are treated like
* unions.
*/
int (*close)(FAR struct file *filep);
ssize_t (*read)(FAR struct file *filep, FAR char *buffer, size_t buflen);
ssize_t (*write)(FAR struct file *filep, FAR const char *buffer, size_t buflen);
off_t (*seek)(FAR struct file *filep, off_t offset, int whence);
int (*ioctl)(FAR struct file *filep, int cmd, unsigned long arg);
int (*mmap)(FAR struct file* filep, struct VmMapRegion *region);
int (*close)(struct file *filep);
ssize_t (*read)(struct file *filep, char *buffer, size_t buflen);
ssize_t (*write)(struct file *filep, const char *buffer, size_t buflen);
off_t (*seek)(struct file *filep, off_t offset, int whence);
int (*ioctl)(struct file *filep, int cmd, unsigned long arg);
int (*mmap)(struct file* filep, struct VmMapRegion *region);
/* The two structures need not be common after this point */
#ifndef CONFIG_DISABLE_POLL
int (*poll)(FAR struct file *filep, poll_table *fds);
int (*poll)(struct file *filep, poll_table *fds);
#endif
int (*unlink)(FAR struct inode *inode);
int (*stat)(struct file *filep, struct stat* st);
int (*fallocate)(struct file* filep, int mode, off_t offset, off_t len);
int (*fallocate64)(struct file *filep, int mode, off64_t offset, off64_t len);
int (*fsync)(struct file *filep);
ssize_t (*readpage)(struct file *filep, char *buffer, size_t buflen);
int (*unlink)(struct Vnode *vnode);
};
/* This structure provides information about the state of a block driver */
@@ -214,31 +221,119 @@ struct file_operations_vfs
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct geometry
{
bool geo_available; /* true: The device is available */
bool geo_mediachanged; /* true: The media has changed since last query */
bool geo_writeenabled; /* true: It is okay to write to this device */
bool geo_available; /* true: The device is available */
bool geo_mediachanged; /* true: The media has changed since last query */
bool geo_writeenabled; /* true: It is okay to write to this device */
unsigned long long geo_nsectors; /* Number of sectors on the device */
size_t geo_sectorsize; /* Size of one sector */
size_t geo_sectorsize; /* Size of one sector */
};
/* This structure is provided by block devices when they register with the
* system. It is used by file systems to perform filesystem transfers. It
* differs from the normal driver vtable in several ways -- most notably in
* that it deals in struct inode vs. struct filep.
* that it deals in struct Vnode vs. struct filep.
*/
struct inode;
struct Vnode;
struct block_operations
{
int (*open)(FAR struct inode *inode);
int (*close)(FAR struct inode *inode);
ssize_t (*read)(FAR struct inode *inode, FAR unsigned char *buffer,
int (*open)(struct Vnode *vnode);
int (*close)(struct Vnode *vnode);
ssize_t (*read)(struct Vnode *vnode, unsigned char *buffer,
unsigned long long start_sector, unsigned int nsectors);
ssize_t (*write)(FAR struct inode *inode, FAR const unsigned char *buffer,
ssize_t (*write)(struct Vnode *vnode, const unsigned char *buffer,
unsigned long long start_sector, unsigned int nsectors);
int (*geometry)(FAR struct inode *inode, FAR struct geometry *geometry);
int (*ioctl)(FAR struct inode *inode, int cmd, unsigned long arg);
int (*unlink)(FAR struct inode *inode);
int (*geometry)(struct Vnode *vnode, struct geometry *geometry);
int (*ioctl)(struct Vnode *vnode, int cmd, unsigned long arg);
int (*unlink)(struct Vnode *vnode);
};
struct mountpt_operations2
{
/* The mountpoint open method differs from the driver open method
* because it receives (1) the vnode that contains the mountpoint
* private data, (2) the relative path into the mountpoint, and (3)
* information to manage privileges.
*/
int (*open)(struct file *filep, const char *relpath,
int oflags, mode_t mode);
/* The following methods must be identical in signature and position
* because the struct file_operations and struct mountpt_operations are
* treated like unions.
*/
int (*close)(struct file *filep);
ssize_t (*read)(struct file *filep, char *buffer, size_t buflen);
ssize_t (*write)(struct file *filep, const char *buffer,
size_t buflen);
off_t (*seek)(struct file *filep, off_t offset, int whence);
int (*ioctl)(struct file *filep, int cmd, unsigned long arg);
int (*mmap)(struct file* filep, LosVmMapRegion *region);
/* The two structures need not be common after this point. The following
* are extended methods needed to deal with the unique needs of mounted
* file systems.
*
* Additional open-file-specific mountpoint operations:
*/
int (*sync)(struct file *filep);
int (*dup)(const struct file *oldp, struct file *newp);
int (*fstat)(const struct file *filep, struct stat *buf);
int (*truncate)(struct file *filep, off_t length);
/* Directory operations */
int (*opendir)(struct Vnode *mountpt, const char *relpath,
struct fs_dirent_s *dir);
int (*closedir)(struct Vnode *mountpt,
struct fs_dirent_s *dir);
int (*readdir)(struct Vnode *mountpt,
struct fs_dirent_s *dir);
int (*rewinddir)(struct Vnode *mountpt,
struct fs_dirent_s *dir);
/* General volume-related mountpoint operations: */
int (*bind)(struct Vnode *blkdriver, const void *data, void **handle, const char *realpath);
int (*unbind)(void *handle, struct Vnode **blkdriver);
int (*statfs)(struct Vnode *mountpt, struct statfs *buf);
int (*virstatfs)(struct Vnode *mountpt, const char* relpath, struct statfs *buf);
/* Operations on paths */
int (*unlink)(struct Vnode *mountpt, const char *relpath);
int (*mkdir)(struct Vnode *mountpt, const char *relpath,
mode_t mode);
int (*rmdir)(struct Vnode *mountpt, const char *relpath);
int (*rename)(struct Vnode *mountpt, const char *oldrelpath,
const char *newrelpath);
int (*stat)(struct Vnode *mountpt, const char *relpath,
struct stat *buf);
int (*utime)(struct Vnode *mountpt, const char *relpath,
const struct tm *times);
int (*chattr)(struct Vnode *mountpt, const char *relpath,
struct IATTR *attr);
loff_t (*seek64)(struct file *filep, loff_t offset, int whence);
int (*getlabel)(void *handle, char* label);
int (*fallocate)(struct file *filep, int mode, off_t offset, off_t len);
int (*fallocate64)(struct file *filep, int mode, off64_t offset, off64_t len);
int (*truncate64)(struct file *filep, off64_t length);
int (*fscheck)(struct Vnode *mountpt, const char *relpath,
struct fs_dirent_s *dir);
int (*map_pages)(LosVmMapRegion *region, LosVmPgFault *pgFault);
ssize_t (*writepage)(struct file *filep, const char *buffer, size_t buflen);
/* NOTE: More operations will be needed here to support: disk usage
* stats file stat(), file attributes, file truncation, etc.
*/
};
struct drv_data
{
const void *ops;
mode_t mode;
void *priv;
};
/* This structure is provided by a filesystem to describe a mount point.
@@ -260,94 +355,12 @@ struct page_mapping {
/* map: full_path(owner) <-> mapping */
struct file_map {
LOS_DL_LIST head;
LosMux lock; /* lock to protect this mapping */
struct page_mapping mapping;
char *owner; /* owner: full path of file */
};
struct mountpt_operations
{
/* The mountpoint open method differs from the driver open method
* 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 *filep, FAR const char *relpath,
int oflags, mode_t mode);
/* The following methods must be identical in signature and position
* because the struct file_operations and struct mountpt_operations are
* treated like unions.
*/
int (*close)(FAR struct file *filep);
ssize_t (*read)(FAR struct file *filep, FAR char *buffer, size_t buflen);
ssize_t (*write)(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
off_t (*seek)(FAR struct file *filep, off_t offset, int whence);
int (*ioctl)(FAR struct file *filep, int cmd, unsigned long arg);
int (*mmap)(FAR struct file* filep, LosVmMapRegion *region);
/* The two structures need not be common after this point. The following
* are extended methods needed to deal with the unique needs of mounted
* file systems.
*
* Additional open-file-specific mountpoint operations:
*/
int (*sync)(FAR struct file *filep);
int (*dup)(FAR const struct file *oldp, FAR struct file *newp);
int (*fstat)(FAR const struct file *filep, FAR struct stat *buf);
int (*truncate)(FAR struct file *filep, off_t length);
/* Directory operations */
int (*opendir)(FAR struct inode *mountpt, FAR const char *relpath,
FAR struct fs_dirent_s *dir);
int (*closedir)(FAR struct inode *mountpt,
FAR struct fs_dirent_s *dir);
int (*readdir)(FAR struct inode *mountpt,
FAR struct fs_dirent_s *dir);
int (*rewinddir)(FAR struct inode *mountpt,
FAR struct fs_dirent_s *dir);
/* General volume-related mountpoint operations: */
int (*bind)(FAR struct inode *blkdriver, FAR const void *data,
FAR void **handle, FAR const char *realpath);
int (*unbind)(FAR void *handle, FAR struct inode **blkdriver);
int (*statfs)(FAR struct inode *mountpt, FAR struct statfs *buf);
int (*virstatfs)(struct inode *mountpt, const char* relpath, struct statfs *buf);
/* Operations on paths */
int (*unlink)(FAR struct inode *mountpt, FAR const char *relpath);
int (*mkdir)(FAR struct inode *mountpt, FAR const char *relpath,
mode_t mode);
int (*rmdir)(FAR struct inode *mountpt, FAR const char *relpath);
int (*rename)(FAR struct inode *mountpt, FAR const char *oldrelpath,
FAR const char *newrelpath);
int (*stat)(FAR struct inode *mountpt, FAR const char *relpath,
FAR struct stat *buf);
int (*utime)(FAR struct inode *mountpt, FAR const char *relpath,
FAR const struct tm *times);
int (*chattr)(FAR struct inode *mountpt, FAR const char *relpath,
struct IATTR *attr);
loff_t (*seek64)(FAR struct file *filep, loff_t offset, int whence);
int (*getlabel)(FAR void *handle, FAR char* label);
int (*fallocate)(FAR struct file *filep, int mode, off_t offset, off_t len);
int (*fallocate64)(FAR struct file *filep, int mode, off64_t offset, off64_t len);
int (*truncate64)(FAR struct file *filep, off64_t length);
int (*fscheck)(FAR struct inode *mountpt, FAR const char *relpath,
FAR struct fs_dirent_s *dir);
int (*map_pages)(LosVmMapRegion *region, LosVmPgFault *pgFault);
ssize_t (*readpage)(struct file *filep, char *buffer, size_t buflen);
ssize_t (*writepage)(struct file *filep, const char *buffer, size_t buflen);
/* NOTE: More operations will be needed here to support: disk usage
* stats file stat(), file attributes, file truncation, etc.
*/
LOS_DL_LIST head;
LosMux lock; /* lock to protect this mapping */
struct page_mapping mapping;
int name_len;
char *rename;
char owner[0]; /* owner: full path of file */
};
#endif /* CONFIG_DISABLE_MOUNTPOINT */
@@ -366,7 +379,7 @@ typedef struct virtual_partition_info
struct fsmap_t
{
const char *fs_filesystemtype;
const struct mountpt_operations *fs_mops;
const struct MountOps *fs_mops;
const BOOL is_mtd_support;
const BOOL is_bdfs;
};
@@ -391,25 +404,10 @@ struct fsmap_t _l LOS_HAL_TABLE_ENTRY(fsmap) = \
*/
/* These are the various kinds of operations that can be associated with
* an inode.
* an vnode.
*/
union inode_ops_u
{
FAR const struct file_operations_vfs *i_ops; /* Driver operations for inode */
#ifndef CONFIG_DISABLE_MOUNTPOINT
FAR const struct block_operations *i_bops; /* Block driver operations */
FAR const struct mountpt_operations *i_mops; /* Operations on a mountpoint */
#endif
#ifdef CONFIG_FS_NAMED_SEMAPHORES
FAR struct nsem_inode_s *i_nsem; /* Named semaphore */
#endif
#ifndef CONFIG_DISABLE_MQUEUE
FAR struct mqueue_inode_s *i_mqueue; /* POSIX message queue */
#endif
};
/* This structure represents one inode in the NuttX pseudo-file system */
/* This structure represents one vnode in the NuttX pseudo-file system */
typedef enum mount_status
{
@@ -417,36 +415,19 @@ typedef enum mount_status
STAT_MOUNTED,
} MOUNT_STATE;
struct inode
{
FAR struct inode *i_peer; /* Link to same level inode */
FAR struct inode *i_child; /* Link to lower level inode */
int16_t i_crefs; /* References to inode */
uint16_t i_flags; /* Flags for inode */
unsigned long mountflags; /* Flags for mount */
union inode_ops_u u; /* Inode operations */
#ifdef LOSCFG_FILE_MODE
unsigned int i_uid;
unsigned int i_gid;
mode_t i_mode; /* Access mode flags */
#endif
FAR void *i_private; /* Per inode driver private data */
MOUNT_STATE e_status;
char i_name[1]; /* Name of inode (variable) */
};
#define FSNODE_SIZE(n) (sizeof(struct inode) + (n))
#define FSNODE_SIZE(n) (sizeof(struct Vnode) + (n))
/* This is the underlying representation of an open file. A file
* descriptor is an index into an array of such types. The type associates
* the file descriptor to the file state and to a set of inode operations.
* the file descriptor to the file state and to a set of vnode operations.
*/
struct file
{
unsigned int f_magicnum; /* file magic number */
int f_oflags; /* Open mode flags */
FAR struct inode *f_inode; /* Driver interface */
struct Vnode *f_vnode; /* Driver interface */
loff_t f_pos; /* File position */
unsigned long f_refcount; /* reference count */
char *f_path; /* File fullpath */
@@ -454,6 +435,8 @@ struct file
const char *f_relpath; /* realpath */
struct page_mapping *f_mapping; /* mapping file to memory */
void *f_dir; /* DIR struct for iterate the directory if open a directory */
const struct file_operations_vfs *ops;
int fd;
};
/* This defines a list of files indexed by the file descriptor */
@@ -502,10 +485,10 @@ struct file_struct
sem_t fs_sem; /* For thread safety */
pid_t fs_holder; /* Holder of sem */
int fs_counts; /* Number of times sem is held */
FAR unsigned char *fs_bufstart; /* Pointer to start of buffer */
FAR unsigned char *fs_bufend; /* Pointer to 1 past end of buffer */
FAR unsigned char *fs_bufpos; /* Current position in buffer */
FAR unsigned char *fs_bufread; /* Pointer to 1 past last buffered read char. */
unsigned char *fs_bufstart; /* Pointer to start of buffer */
unsigned char *fs_bufend; /* Pointer to 1 past end of buffer */
unsigned char *fs_bufpos; /* Current position in buffer */
unsigned char *fs_bufread; /* Pointer to 1 past last buffered read char. */
#endif
uint16_t fs_oflags; /* Open mode flags */
uint8_t fs_flags; /* Stream flags */
@@ -539,21 +522,21 @@ void fs_initialize(void);
* Name: register_driver
*
* Description:
* Register a character driver inode the pseudo file system.
* Register a character driver vnode the pseudo file system.
*
* Input Parameters:
* path - The path to the inode to create
* path - The path to the vnode to create
* fops - The file operations structure
* mode - Access privileges (not used)
* priv - Private, user data that will be associated with the inode.
* priv - Private, user data that will be associated with the vnode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* Zero on success (with the vnode point in 'vnode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
* vnode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* EEXIST - An vnode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
* Attention:
@@ -565,15 +548,15 @@ void fs_initialize(void);
*
****************************************************************************/
int register_driver(FAR const char *path,
FAR const struct file_operations_vfs *fops, mode_t mode,
FAR void *priv);
int register_driver(const char *path,
const struct file_operations_vfs *fops, mode_t mode,
void *priv);
/****************************************************************************
* Name: register_blockdriver
*
* Description:
* Register a block driver inode the pseudo file system.
* Register a block driver vnode the pseudo file system.
*
* Attention:
* This function should be called after los_vfs_init has been called.
@@ -583,38 +566,38 @@ int register_driver(FAR const char *path,
* The bops must pointed the right functions, otherwise the system will crash when the device is being operated.
*
* Input Parameters:
* path - The path to the inode to create
* path - The path to the vnode to create
* bops - The block driver operations structure
* mode - Access privileges (not used)
* priv - Private, user data that will be associated with the inode.
* priv - Private, user data that will be associated with the vnode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* Zero on success (with the vnode point in 'vnode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
* vnode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* EEXIST - An vnode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
int register_blockdriver(FAR const char *path,
FAR const struct block_operations *bops,
mode_t mode, FAR void *priv);
int register_blockdriver(const char *path,
const struct block_operations *bops,
mode_t mode, void *priv);
#endif
/****************************************************************************
* Name: unregister_driver
*
* Description:
* Remove the character driver inode at 'path' from the pseudo-file system
* Remove the character driver vnode at 'path' from the pseudo-file system
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* Zero on success (with the vnode point in 'vnode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
* vnode_reserve):
*
* EBUSY - Resource is busy ,not permit for this operation.
* ENOENT - 'path' is invalid for this operation.
@@ -626,21 +609,21 @@ int register_blockdriver(FAR const char *path,
* The block device node referred by parameter path must be really exist.
****************************************************************************/
int unregister_driver(FAR const char *path);
int unregister_driver(const char *path);
/****************************************************************************
* Name: unregister_blockdriver
*
* Description:
* Remove the block driver inode at 'path' from the pseudo-file system
* Remove the block driver vnode at 'path' from the pseudo-file system
*
* Input Parameters:
* path - The path that the inode to be destroyed.
* path - The path that the vnode to be destroyed.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* Zero on success (with the vnode point in 'vnode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
* vnode_reserve):
*
* EBUSY - Resource is busy ,not permit for this operation.
* ENOENT - 'path' is invalid for this operation.
@@ -653,7 +636,7 @@ int unregister_driver(FAR const char *path);
*
****************************************************************************/
int unregister_blockdriver(FAR const char *path);
int unregister_blockdriver(const char *path);
/****************************************************************************
* Name: files_initlist
@@ -664,7 +647,7 @@ int unregister_blockdriver(FAR const char *path);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
void files_initlist(FAR struct filelist *list);
void files_initlist(struct filelist *list);
#endif
/****************************************************************************
@@ -676,14 +659,14 @@ void files_initlist(FAR struct filelist *list);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
void files_releaselist(FAR struct filelist *list);
void files_releaselist(struct filelist *list);
#endif
/****************************************************************************
* Name: file_dup2
*
* Description:
* Assign an inode to a specific files structure. This is the heart of
* Assign an vnode to a specific files structure. This is the heart of
* dup2.
*
* Equivalent to the non-standard fs_dupfd2() function except that it
@@ -697,7 +680,7 @@ void files_releaselist(FAR struct filelist *list);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int file_dup2(FAR struct file *filep1, FAR struct file *filep2);
int file_dup2(struct file *filep1, struct file *filep2);
#endif
/****************************************************************************
@@ -738,7 +721,7 @@ int fs_dupfd(int fd, int minfd);
*
****************************************************************************/
int file_dup(FAR struct file *filep, int minfd);
int file_dup(struct file *filep, int minfd);
/****************************************************************************
* Name: fs_dupfd2 OR dup2
@@ -768,49 +751,79 @@ int fs_dupfd2(int fd1, int fd2);
* Name: open_blockdriver
*
* Description:
* Return the inode of the block driver specified by 'pathname'
* Return the vnode of the block driver specified by 'pathname'
*
* Input Parameters:
* pathname - the full path to the block driver to be opened
* mountflags - if MS_RDONLY is not set, then driver must support write
* operations (see include/sys/mount.h)
* ppinode - address of the location to return the inode reference
* ppvnode - address of the location to return the vnode reference
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* EINVAL - pathname or pinode is NULL
* EINVAL - pathname or pvnode is NULL
* ENOENT - No block driver of this name is registered
* ENOTBLK - The inode associated with the pathname is not a block driver
* ENOTBLK - The vnode associated with the pathname is not a block driver
* EACCESS - The MS_RDONLY option was not set but this driver does not
* support write access
*
* Aattention:
* The parameter path must point a valid string, which end with the terminating null byte.
* The total length of parameter path must less than the value defined by PATH_MAX.
* The parameter ppinode must point a valid memory, which size must be enough for storing struct inode.
* The parameter ppvnode must point a valid memory, which size must be enough for storing struct Vnode.
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int open_blockdriver(FAR const char *pathname, int mountflags,
FAR struct inode **ppinode);
int open_blockdriver(const char *pathname, int mountflags,
struct Vnode **ppvnode);
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: find_blockdriver
*
* Description:
* Return the inode of the block driver specified by 'pathname'
*
* Input Parameters:
* pathname - The full path to the block driver to be located
* mountflags - If MS_RDONLY is not set, then driver must support write
* operations (see include/sys/mount.h)
* ppinode - Address of the location to return the inode reference
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* ENOENT - No block driver of this name is registered
* ENOTBLK - The inode associated with the pathname is not a block driver
* EACCESS - The MS_RDONLY option was not set but this driver does not
* support write access
*
****************************************************************************/
int find_blockdriver(const char *pathname, int mountflags,
struct Vnode **vpp);
/****************************************************************************
* Name: close_blockdriver
*
* Description:
* Call the close method and release the inode
* Call the close method and release the vnode
*
* Input Parameters:
* inode - reference to the inode of a block driver opened by open_blockdriver
* vnode - reference to the vnode of a block driver opened by open_blockdriver
*
* Returned Value:
* Returns zero on success or a negated errno on failure:
*
* EINVAL - inode is NULL
* ENOTBLK - The inode is not a block driver
* EINVAL - vnode is NULL
* ENOTBLK - The vnode is not a block driver
*
* Attention:
* This function should be called after open_blockdriver has been called.
@@ -818,7 +831,7 @@ int open_blockdriver(FAR const char *pathname, int mountflags,
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int close_blockdriver(FAR struct inode *inode);
int close_blockdriver(struct Vnode *vnode);
#endif
/****************************************************************************
@@ -865,7 +878,7 @@ int fs_ioctl(int fd, int req, unsigned long arg);
#if CONFIG_NFILE_STREAMS > 0
struct tcb_s; /* Forward reference */
FAR struct file_struct *fs_fdopen(int fd, int oflags);
struct file_struct *fs_fdopen(int fd, int oflags);
#endif
/****************************************************************************
@@ -878,7 +891,7 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags);
****************************************************************************/
#if CONFIG_NFILE_STREAMS > 0
int lib_flushall(FAR struct streamlist *list);
int lib_flushall(struct streamlist *list);
#endif
/****************************************************************************
@@ -912,7 +925,7 @@ ssize_t lib_sendfile(int outfd, int infd, off_t *offset, size_t count);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int fs_getfilep(int fd, FAR struct file **filep);
int fs_getfilep(int fd, struct file **filep);
#endif
/****************************************************************************
@@ -939,7 +952,7 @@ int fs_getfilep(int fd, FAR struct file **filep);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes);
ssize_t file_read(struct file *filep, void *buf, size_t nbytes);
#endif
/****************************************************************************
@@ -953,7 +966,7 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes);
ssize_t file_write(struct file *filep, const void *buf, size_t nbytes);
#endif
/****************************************************************************
@@ -967,7 +980,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
ssize_t file_pread(FAR struct file *filep, FAR void *buf, size_t nbytes,
ssize_t file_pread(struct file *filep, void *buf, size_t nbytes,
off_t offset);
#endif
@@ -982,7 +995,7 @@ ssize_t file_pread(FAR struct file *filep, FAR void *buf, size_t nbytes,
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
ssize_t file_pwrite(FAR struct file *filep, FAR const void *buf,
ssize_t file_pwrite(struct file *filep, const void *buf,
size_t nbytes, off_t offset);
#endif
@@ -997,7 +1010,7 @@ ssize_t file_pwrite(FAR struct file *filep, FAR const void *buf,
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
off_t file_seek(FAR struct file *filep, off_t offset, int whence);
off_t file_seek(struct file *filep, off_t offset, int whence);
#endif
/****************************************************************************
@@ -1011,7 +1024,7 @@ off_t file_seek(FAR struct file *filep, off_t offset, int whence);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int file_fsync(FAR struct file *filep);
int file_fsync(struct file *filep);
#endif
/****************************************************************************
@@ -1034,7 +1047,7 @@ int file_fsync(FAR struct file *filep);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
int file_vfcntl(FAR struct file *filep, int cmd, va_list ap);
int file_vfcntl(struct file *filep, int cmd, va_list ap);
#endif
/****************************************************************************
@@ -1048,9 +1061,57 @@ int file_vfcntl(FAR struct file *filep, int cmd, va_list ap);
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
off64_t file_seek64(FAR struct file *filep, off64_t offset, int whence);
off64_t file_seek64(struct file *filep, off64_t offset, int whence);
#endif
/****************************************************************************
* Name: files_allocate
*
* Description:
* Allocate a struct files instance and associate it with an vnode instance.
* Returns the file descriptor == index into the files array.
*
****************************************************************************/
int files_allocate(struct Vnode *vnode, int oflags, off_t pos,void *priv, int minfd);
/****************************************************************************
* Name: files_close
*
* Description:
* Close an vnode (if open)
*
* Assumuptions:
* Caller holds the list semaphore because the file descriptor will be freed.
*
****************************************************************************/
int files_close(int fd);
/****************************************************************************
* Name: files_release
*
* Assumuptions:
* Similar to files_close(). Called only from open() logic on error
* conditions.
*
****************************************************************************/
void files_release(int fd);
/****************************************************************************
* Name: files_initialize
*
* Description:
* This is called from the FS initialization logic to configure the files.
*
****************************************************************************/
void weak_function files_initialize(void);
int vfs_normalize_path(const char *directory, const char *filename, char **pathname);
int vfs_normalize_pathat(int fd, const char *filename, char **pathname);
#ifdef __cplusplus
#if __cplusplus
}