diff --git a/fs/driver/driver.h b/fs/driver/driver.h index b8d9959821..b2154d9273 100644 --- a/fs/driver/driver.h +++ b/fs/driver/driver.h @@ -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 * diff --git a/fs/driver/fs_blockpartition.c b/fs/driver/fs_blockpartition.c index a4b3cf94d8..f39075ec40 100644 --- a/fs/driver/fs_blockpartition.c +++ b/fs/driver/fs_blockpartition.c @@ -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; +} diff --git a/fs/driver/fs_mtdpartition.c b/fs/driver/fs_mtdpartition.c index 655846b858..1641e72370 100644 --- a/fs/driver/fs_mtdpartition.c +++ b/fs/driver/fs_mtdpartition.c @@ -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; } diff --git a/fs/partition/fs_partition.c b/fs/partition/fs_partition.c index 3f86a645f6..4707584058 100644 --- a/fs/partition/fs_partition.c +++ b/fs/partition/fs_partition.c @@ -25,13 +25,21 @@ #include #include +#include +#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++) {