forked from nuttx/nuttx-update
fs/partition: register partition device if caller doesn't provide handler
to avoid the duplication of common logic Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
5528c84c03
commit
dde8ae468e
4 changed files with 175 additions and 45 deletions
|
@ -75,6 +75,35 @@ int find_blockdriver(FAR const char *pathname, int mountflags,
|
|||
FAR struct inode **ppinode);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: register_partition_with_inode
|
||||
*
|
||||
* Description:
|
||||
* Register a block partition driver inode the pseudo file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* partition - The path to the partition inode
|
||||
* parent - the parent inode
|
||||
* firstsector - The offset in sectors to the partition
|
||||
* nsectors - The number of sectors in the partition
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success (with the inode point in 'inode'); A negated errno
|
||||
* value is returned on a failure (all error values returned by
|
||||
* inode_reserve):
|
||||
*
|
||||
* EINVAL - 'path' is invalid for this operation
|
||||
* EEXIST - An inode already exists at 'path'
|
||||
* ENOMEM - Failed to allocate in-memory resources for the operation
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
int register_partition_with_inode(FAR const char *partition,
|
||||
mode_t mode, FAR struct inode *parent,
|
||||
off_t firstsector, off_t nsectors);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: block_proxy
|
||||
*
|
||||
|
@ -98,6 +127,35 @@ int find_blockdriver(FAR const char *pathname, int mountflags,
|
|||
int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: register_partition_with_mtd
|
||||
*
|
||||
* Description:
|
||||
* Register a mtd partition driver inode the pseudo file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* partition - The path to the partition inode
|
||||
* parent - The parent mtd instance
|
||||
* firstblock - The offset in block to the partition
|
||||
* nblocks - The number of block in the partition
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success (with the inode point in 'inode'); A negated errno
|
||||
* value is returned on a failure (all error values returned by
|
||||
* inode_reserve):
|
||||
*
|
||||
* EINVAL - 'path' is invalid for this operation
|
||||
* EEXIST - An inode already exists at 'path'
|
||||
* ENOMEM - Failed to allocate in-memory resources for the operation
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD
|
||||
int register_partition_with_mtd(FAR const char *partition,
|
||||
mode_t mode, FAR struct mtd_dev_s *parent,
|
||||
off_t firstblock, off_t nblocks);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mtd_proxy
|
||||
*
|
||||
|
|
|
@ -294,14 +294,14 @@ static int part_unlink(FAR struct inode *inode)
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: register_blockpartition
|
||||
* Name: register_blockpartition/register_partition_with_inode
|
||||
*
|
||||
* Description:
|
||||
* Register a block partition driver inode the pseudo file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* partition - The path to the partition inode
|
||||
* parent - The path to the parent inode
|
||||
* parent - The parent path or inode
|
||||
* firstsector - The offset in sectors to the partition
|
||||
* nsectors - The number of sectors in the partition
|
||||
*
|
||||
|
@ -316,44 +316,35 @@ static int part_unlink(FAR struct inode *inode)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int register_blockpartition(FAR const char *partition,
|
||||
mode_t mode, FAR const char *parent,
|
||||
off_t firstsector, off_t nsectors)
|
||||
int register_partition_with_inode(FAR const char *partition,
|
||||
mode_t mode, FAR struct inode *parent,
|
||||
off_t firstsector, off_t nsectors)
|
||||
{
|
||||
FAR struct part_struct_s *dev;
|
||||
struct geometry geo;
|
||||
int ret;
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Allocate a partition device structure */
|
||||
|
||||
dev = kmm_zalloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
if (dev == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
inode_addref(parent);
|
||||
dev->parent = parent;
|
||||
dev->firstsector = firstsector;
|
||||
dev->nsectors = nsectors;
|
||||
|
||||
/* Find the block driver */
|
||||
|
||||
if (mode & (S_IWOTH | S_IWGRP | S_IWUSR))
|
||||
{
|
||||
ret = find_blockdriver(parent, 0, &dev->parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = find_blockdriver(parent, MS_RDONLY, &dev->parent);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_free;
|
||||
}
|
||||
|
||||
/* Get sector size */
|
||||
|
||||
ret = dev->parent->u.i_bops->geometry(dev->parent, &geo);
|
||||
ret = parent->u.i_bops->geometry(parent, &geo);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_free;
|
||||
|
@ -366,14 +357,43 @@ int register_blockpartition(FAR const char *partition,
|
|||
ret = register_blockdriver(partition, &g_part_bops, mode, dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_release;
|
||||
goto errout_free;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_release:
|
||||
inode_release(dev->parent);
|
||||
errout_free:
|
||||
inode_release(parent);
|
||||
kmm_free(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int register_blockpartition(FAR const char *partition,
|
||||
mode_t mode, FAR const char *parent,
|
||||
off_t firstsector, off_t nsectors)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
int ret;
|
||||
|
||||
/* Find the block driver */
|
||||
|
||||
if (mode & (S_IWOTH | S_IWGRP | S_IWUSR))
|
||||
{
|
||||
ret = find_blockdriver(parent, 0, &inode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = find_blockdriver(parent, MS_RDONLY, &inode);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = register_partition_with_inode(partition, mode,
|
||||
inode, firstsector, nsectors);
|
||||
inode_release(inode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -37,14 +37,14 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: register_mtdpartition
|
||||
* Name: register_mtdpartition/register_partition_with_mtd
|
||||
*
|
||||
* Description:
|
||||
* Register a mtd partition driver inode the pseudo file system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* partition - The path to the partition inode
|
||||
* parent - The path to the parent inode
|
||||
* parent - The parent path or mtd instance
|
||||
* firstblock - The offset in block to the partition
|
||||
* nblocks - The number of block in the partition
|
||||
*
|
||||
|
@ -59,26 +59,15 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int register_mtdpartition(FAR const char *partition,
|
||||
mode_t mode, FAR const char *parent,
|
||||
off_t firstblock, off_t nblocks)
|
||||
int register_partition_with_mtd(FAR const char *partition,
|
||||
mode_t mode, FAR struct mtd_dev_s *parent,
|
||||
off_t firstblock, off_t nblocks)
|
||||
{
|
||||
FAR struct mtd_dev_s *part;
|
||||
FAR struct inode *mtd;
|
||||
int ret;
|
||||
|
||||
/* Find the mtd driver */
|
||||
|
||||
ret = find_mtddriver(parent, &mtd);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create the mtd partition */
|
||||
|
||||
part = mtd_partition(mtd->u.i_mtd, firstblock, nblocks);
|
||||
inode_release(mtd);
|
||||
part = mtd_partition(parent, firstblock, nblocks);
|
||||
if (part == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
@ -90,11 +79,29 @@ int register_mtdpartition(FAR const char *partition,
|
|||
|
||||
/* Register the mtd partition */
|
||||
|
||||
ret = register_mtddriver(partition, part, mode, part);
|
||||
return register_mtddriver(partition, part, mode, part);
|
||||
}
|
||||
|
||||
int register_mtdpartition(FAR const char *partition,
|
||||
mode_t mode, FAR const char *parent,
|
||||
off_t firstblock, off_t nblocks)
|
||||
{
|
||||
FAR struct inode *mtd;
|
||||
int ret;
|
||||
|
||||
/* Find the mtd driver */
|
||||
|
||||
ret = find_mtddriver(parent, &mtd);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
/* Register the mtd partition */
|
||||
|
||||
ret = register_partition_with_mtd(partition, mode,
|
||||
mtd->u.i_mtd, firstblock, nblocks);
|
||||
inode_release(mtd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -25,13 +25,21 @@
|
|||
#include <sys/mount.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "driver/driver.h"
|
||||
#include "partition.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct partition_register_s
|
||||
{
|
||||
FAR struct partition_state_s *state;
|
||||
FAR const char *dir;
|
||||
};
|
||||
|
||||
typedef CODE int
|
||||
(*partition_parser_t)(FAR struct partition_state_s *state,
|
||||
partition_handler_t handler,
|
||||
|
@ -41,6 +49,9 @@ typedef CODE int
|
|||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void register_partition(FAR struct partition_s *part,
|
||||
FAR void *arg);
|
||||
|
||||
static int parse_partition(FAR struct partition_state_s *state,
|
||||
partition_handler_t handler,
|
||||
FAR void *arg);
|
||||
|
@ -70,6 +81,30 @@ static const partition_parser_t g_parser[] =
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void register_partition(FAR struct partition_s *part, FAR void *arg)
|
||||
{
|
||||
if (part->name[0] != '\0')
|
||||
{
|
||||
FAR struct partition_register_s *reg = arg;
|
||||
FAR struct partition_state_s *state = reg->state;
|
||||
char path[PATH_MAX];
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s", reg->dir, part->name);
|
||||
if (state->blk != NULL)
|
||||
{
|
||||
register_partition_with_inode(path, 0660, state->blk,
|
||||
part->firstblock, part->nblocks);
|
||||
}
|
||||
#ifdef CONFIG_MTD
|
||||
else
|
||||
{
|
||||
register_partition_with_mtd(path, 0660, state->mtd,
|
||||
part->firstblock, part->nblocks);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: parse_partition
|
||||
*
|
||||
|
@ -92,6 +127,16 @@ static int parse_partition(FAR struct partition_state_s *state,
|
|||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct partition_register_s reg =
|
||||
{
|
||||
state, arg ? arg : "/dev"
|
||||
};
|
||||
|
||||
if (handler == NULL)
|
||||
{
|
||||
handler = register_partition;
|
||||
arg = ®
|
||||
}
|
||||
|
||||
for (i = 0; g_parser[i] != NULL; i++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue