diff --git a/fs/Kconfig b/fs/Kconfig index ae15733276..aa5dd9f70c 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -77,6 +77,7 @@ source fs/semaphore/Kconfig source fs/mqueue/Kconfig source fs/shm/Kconfig source fs/mmap/Kconfig +source fs/partition/Kconfig source fs/fat/Kconfig source fs/nfs/Kconfig source fs/nxffs/Kconfig diff --git a/fs/Makefile b/fs/Makefile index 1ffea7cae0..e77f76c8b5 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -63,6 +63,7 @@ ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) include mount/Make.defs +include partition/Make.defs include fat/Make.defs include romfs/Make.defs include cromfs/Make.defs diff --git a/fs/driver/Make.defs b/fs/driver/Make.defs index 12bde01d43..1222879815 100644 --- a/fs/driver/Make.defs +++ b/fs/driver/Make.defs @@ -44,6 +44,7 @@ CSRCS += fs_registerdriver.c fs_unregisterdriver.c ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) CSRCS += fs_registerblockdriver.c fs_unregisterblockdriver.c CSRCS += fs_findblockdriver.c fs_openblockdriver.c fs_closeblockdriver.c +CSRCS += fs_blockpartition.c ifneq ($(CONFIG_DISABLE_PSEUDOFS_OPERATIONS),y) CSRCS += fs_blockproxy.c diff --git a/fs/driver/fs_blockpartition.c b/fs/driver/fs_blockpartition.c new file mode 100644 index 0000000000..48e383ba62 --- /dev/null +++ b/fs/driver/fs_blockpartition.c @@ -0,0 +1,348 @@ +/**************************************************************************** + * fs/driver/fs_blockpartition.c + * + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Xiang Xiao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "driver/driver.h" +#include "inode/inode.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct part_struct_s +{ + FAR struct inode *parent; + size_t firstsector; + size_t nsectors; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int part_open(FAR struct inode *inode); +static int part_close(FAR struct inode *inode); +static ssize_t part_read(FAR struct inode *inode, unsigned char *buffer, + size_t start_sector, unsigned int nsectors); +#ifdef CONFIG_FS_WRITABLE +static ssize_t part_write(FAR struct inode *inode, const unsigned char *buffer, + size_t start_sector, unsigned int nsectors); +#endif +static int part_geometry(FAR struct inode *inode, struct geometry *geometry); +static int part_ioctl(FAR struct inode *inode, int cmd, unsigned long arg); + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int part_unlink(FAR struct inode *inode); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct block_operations g_part_bops = +{ + part_open, /* open */ + part_close, /* close */ + part_read, /* read */ +#ifdef CONFIG_FS_WRITABLE + part_write, /* write */ +#else + NULL, /* write */ +#endif + part_geometry, /* geometry */ + part_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , part_unlink /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: part_open + * + * Description: Open the block device + * + ****************************************************************************/ + +static int part_open(FAR struct inode *inode) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + int ret = OK; + + /* Open the parent block device */ + + if (parent->u.i_bops->open) + { + ret = parent->u.i_bops->open(parent); + } + + return ret; +} + +/**************************************************************************** + * Name: part_close + * + * Description: close the block device + * + ****************************************************************************/ + +static int part_close(FAR struct inode *inode) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + int ret = OK; + + if (parent->u.i_bops->close) + { + ret = parent->u.i_bops->close(parent); + } + + return ret; +} + +/**************************************************************************** + * Name: part_read + * + * Description: Read the specified number of sectors + * + ****************************************************************************/ + +static ssize_t part_read(FAR struct inode *inode, unsigned char *buffer, + size_t start_sector, unsigned int nsectors) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + + if (start_sector + nsectors > dev->nsectors) + { + nsectors = dev->nsectors - start_sector; + } + + start_sector += dev->firstsector; + + return parent->u.i_bops->read(parent, buffer, start_sector, nsectors); +} + +/**************************************************************************** + * Name: part_write + * + * Description: Write (or buffer) the specified number of sectors + * + ****************************************************************************/ + +#ifdef CONFIG_FS_WRITABLE +static ssize_t part_write(FAR struct inode *inode, const unsigned char *buffer, + size_t start_sector, unsigned int nsectors) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + + if (start_sector + nsectors > dev->nsectors) + { + nsectors = dev->nsectors - start_sector; + } + + start_sector += dev->firstsector; + + return parent->u.i_bops->write(parent, buffer, start_sector, nsectors); +} +#endif + +/**************************************************************************** + * Name: part_geometry + * + * Description: Return device geometry + * + ****************************************************************************/ + +static int part_geometry(FAR struct inode *inode, struct geometry *geometry) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + int ret; + + ret = parent->u.i_bops->geometry(parent, geometry); + if (ret >= 0) + { + geometry->geo_nsectors = dev->nsectors; + } + + return ret; +} + +/**************************************************************************** + * Name: part_ioctl + * + * Description: Return device geometry + * + ****************************************************************************/ + +static int part_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + int ret = -ENOTTY; + + if (parent->u.i_bops->ioctl) + { + ret = parent->u.i_bops->ioctl(parent, cmd, arg); + if (ret >= 0 && cmd == BIOC_XIPBASE) + { + FAR void **base = (FAR void **)arg; + struct geometry geo; + + ret = parent->u.i_bops->geometry(parent, &geo); + if (ret >= 0) + { + *base += dev->firstsector * geo.geo_sectorsize; + } + } + } + + return ret; +} + +/**************************************************************************** + * Name: part_unlink + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int part_unlink(FAR struct inode *inode) +{ + FAR struct part_struct_s *dev = inode->i_private; + FAR struct inode *parent = dev->parent; + + inode_release(parent); + kmm_free(dev); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: register_blockpartition + * + * 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 + * 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 + * + ****************************************************************************/ + +int register_blockpartition(FAR const char *partition, + mode_t mode, FAR const char *parent, + size_t firstsector, size_t nsectors) +{ + FAR struct part_struct_s *dev; + int ret; + + /* Allocate a partition device structure */ + + dev = kmm_zalloc(sizeof(*dev)); + if (!dev) + { + return -ENOMEM; + } + + 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; + } + + /* Inode private data is a reference to the partition device structure */ + + ret = register_blockdriver(partition, &g_part_bops, mode, dev); + if (ret < 0) + { + goto errout_release; + } + + return OK; + +errout_release: + inode_release(dev->parent); +errout_free: + kmm_free(dev); + return ret; +} + diff --git a/fs/partition/Kconfig b/fs/partition/Kconfig new file mode 100644 index 0000000000..584b602835 --- /dev/null +++ b/fs/partition/Kconfig @@ -0,0 +1,16 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if !DISABLE_MOUNTPOINT + +menu "Partition Table" + +config PTABLE_PARTITION + bool "PTABLE support" + default n + +endmenu + +endif diff --git a/fs/partition/Make.defs b/fs/partition/Make.defs new file mode 100644 index 0000000000..6c084c9118 --- /dev/null +++ b/fs/partition/Make.defs @@ -0,0 +1,51 @@ +############################################################################ +# fs/partition/Make.defs +# +# Copyright (C) 2018 Pinecone Inc. All rights reserved. +# Author: Xiang Xiao +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Don't build anything if mountpoint doesn't support + +ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) + +CSRCS += fs_partition.c + +ifeq ($(CONFIG_PTABLE_PARTITION),y) +CSRCS += fs_ptable.c +endif + +# Include partition build support + +DEPPATH += --dep-path partition +VPATH += :partition + +endif diff --git a/fs/partition/fs_partition.c b/fs/partition/fs_partition.c new file mode 100644 index 0000000000..9ec773e630 --- /dev/null +++ b/fs/partition/fs_partition.c @@ -0,0 +1,209 @@ +/**************************************************************************** + * fs/partition/fs_partition.c + * + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Xiang Xiao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "partition.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef CODE int + (*partition_parser_t)(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg); + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int parse_partition(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_PTABLE_PARTITION +int parse_ptable_partition(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const partition_parser_t g_parser[] = +{ +#ifdef CONFIG_PTABLE_PARTITION + parse_ptable_partition, +#endif + NULL +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: parse_partition + * + * Description: + * parse the partition table. + * + * Input Parameters: + * state - The partition table state + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * Zero on success; A negated errno value is returned on a failure + * + ****************************************************************************/ + +static int parse_partition(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg) +{ + int i, ret = 0; + + for (i = 0; g_parser[i] != NULL; i++) + { + ret = g_parser[i](state, handler, arg); + if (ret >= 0) + { + break; + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: parse_block_partition + * + * Description: + * parse the partition table on a block device. + * + * Input Parameters: + * path - The block device to be parsed + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * Zero on success; A negated errno value is returned on a failure + * + ****************************************************************************/ + +int parse_block_partition(FAR const char *path, + partition_handler_t handler, + FAR void *arg) +{ + struct partition_state_s state; + struct geometry geo; + int ret; + + ret = open_blockdriver(path, MS_RDONLY, &state.blk); + if (ret < 0) + { + return ret; + } + + ret = state.blk->u.i_bops->geometry(state.blk, &geo); + if (ret >= 0) + { + state.mtd = NULL; + state.blocksize = geo.geo_sectorsize; + state.erasesize = geo.geo_sectorsize; + state.nblocks = geo.geo_nsectors; + + ret = parse_partition(&state, handler, arg); + } + + close_blockdriver(state.blk); + return ret; +} + +/**************************************************************************** + * Name: parse_mtd_partition + * + * Description: + * parse the partition table on a mtd device. + * + * Input Parameters: + * mtd - The MTD device to be parsed + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * Zero on success; A negated errno value is returned on a failure + * + ****************************************************************************/ + +int parse_mtd_partition(FAR struct mtd_dev_s *mtd, + partition_handler_t handler, + FAR void *arg) +{ + struct partition_state_s state; + struct mtd_geometry_s geo; + int ret; + + ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)&geo); + if (ret < 0) + { + return ret; + } + + state.blk = NULL; + state.mtd = mtd; + state.blocksize = geo.blocksize; + state.erasesize = geo.erasesize; + state.nblocks = geo.neraseblocks; + state.nblocks *= geo.erasesize / geo.blocksize; + + return parse_partition(&state, handler, arg); +} + diff --git a/fs/partition/fs_ptable.c b/fs/partition/fs_ptable.c new file mode 100644 index 0000000000..366d9522bf --- /dev/null +++ b/fs/partition/fs_ptable.c @@ -0,0 +1,168 @@ +/**************************************************************************** + * fs/partition/fs_ptable.c + * + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Xiang Xiao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "partition.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PTABLE_MAGIC_LEN 8 +#define PTABLE_VERSION_LEN 8 +#define PTABLE_NAME_LEN 16 + +#define PTABLE_MAGIC "PTABLE0" +#define PTABLE_FLAG_END (1 << 0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ptable_entry_s +{ + char name[PTABLE_NAME_LEN]; + uint64_t offset; + uint64_t length; + uint64_t flags; + uint64_t reserve; +}; + +struct ptable_s +{ + char magic[PTABLE_MAGIC_LEN]; + char version[PTABLE_VERSION_LEN]; + struct ptable_entry_s entries[]; +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: parse_ptable_partition + * + * Description: + * parse the PTABLE partition table. + * + * Input Parameters: + * state - The partition table state + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * Zero on success; A negated errno value is returned on a failure + * + ****************************************************************************/ + +int parse_ptable_partition(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg) +{ + FAR struct ptable_entry_s *entry; + FAR struct ptable_s *ptable; + size_t blkpererase; + size_t block; + int ret = OK; + + /* Allocate one erase block memory */ + + ptable = kmm_malloc(state->erasesize); + if (ptable == NULL) + { + return -ENOMEM; + } + + /* PTABLE locate in the first or last erase block */ + + blkpererase = state->erasesize / state->blocksize; + for (block = 0; + block < state->nblocks; + block += state->nblocks - blkpererase) + { + ret = read_partition_block(state, ptable, block, blkpererase); + if (ret < 0) + { + goto out; + } + + if (strcmp(ptable->magic, PTABLE_MAGIC) == 0) + { + break; /* Find the magic number */ + } + } + + if (block >= state->nblocks) + { + ret = -EFTYPE; + goto out; + } + + entry = ptable->entries; + while (!(entry->flags & PTABLE_FLAG_END)) + { + struct partition_s part; + + /* Convert the entry to partition */ + + strncpy(part.name, entry->name, sizeof(part.name)); + part.index = entry - ptable->entries; + part.firstblock = entry->offset / state->blocksize; + part.nblocks = entry->length / state->blocksize; + part.blocksize = state->blocksize; + + /* Notify the caller */ + + handler(&part, arg); + + /* Move to the next entry */ + + entry++; + if ((uintptr_t)entry - (uintptr_t)ptable >= state->erasesize) + { + break; /* Exit, at the end of erase block */ + } + } + +out: + kmm_free(ptable); + return ret; +} + diff --git a/fs/partition/partition.h b/fs/partition/partition.h new file mode 100644 index 0000000000..df3dbf145f --- /dev/null +++ b/fs/partition/partition.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * fs/partition/partition.h + * + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Xiang Xiao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __FS_PARTITION_PARTITION_H +#define __FS_PARTITION_PARTITION_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifndef CONFIG_DISABLE_MOUNTPOINT + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct partition_state_s +{ + FAR struct mtd_dev_s *mtd; + FAR struct inode *blk; + size_t nblocks; + size_t blocksize; + size_t erasesize; +}; + +/**************************************************************************** + * Public Inline Functions + ****************************************************************************/ + +static inline int read_partition_block(FAR struct partition_state_s *state, + FAR void *buffer, size_t startblock, + size_t nblocks) +{ + if (state->blk) + { + return state->blk->u.i_bops->read(state->blk, buffer, startblock, nblocks); + } + else + { + return state->mtd->bread(state->mtd, startblock, nblocks, buffer); + } +} + +#endif /* CONFIG_DISABLE_MOUNTPOINT */ + +#endif /* __FS_PARTITION_PARTITION_H */ diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 49be56637b..64a742c63c 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -547,6 +547,35 @@ int register_blockdriver(FAR const char *path, mode_t mode, FAR void *priv); #endif +/**************************************************************************** + * Name: register_blockpartition + * + * 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 + * 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_blockpartition(FAR const char *partition, + mode_t mode, FAR const char *parent, + size_t firstsector, size_t nsectors); +#endif + /**************************************************************************** * Name: unregister_driver * diff --git a/include/nuttx/fs/partition.h b/include/nuttx/fs/partition.h new file mode 100644 index 0000000000..5addfd116e --- /dev/null +++ b/include/nuttx/fs/partition.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * include/nuttx/fs/partition.h + * + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Xiang Xiao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_FS_PARTITION_H +#define __INCLUDE_NUTTX_FS_PARTITION_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifndef CONFIG_DISABLE_MOUNTPOINT + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct partition_s +{ + char name[NAME_MAX+1]; + size_t index; + size_t firstblock; + size_t nblocks; + size_t blocksize; +}; + +typedef CODE void + (*partition_handler_t)(FAR struct partition_s *part, FAR void *arg); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: parse_block_partition + * + * Description: + * parse the partition table on a block device. + * + * Input Parameters: + * path - The block device to be parsed + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * Zero on success; A negated errno value is returned on a failure + * + ****************************************************************************/ + +int parse_block_partition(FAR const char *path, + partition_handler_t handler, + FAR void *arg); + +/**************************************************************************** + * Name: parse_mtd_partition + * + * Description: + * parse the partition table on a mtd device. + * + * Input Parameters: + * mtd - The MTD device to be parsed + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * Zero on success; A negated errno value is returned on a failure + * + ****************************************************************************/ + +struct mtd_dev_s; +int parse_mtd_partition(FAR struct mtd_dev_s *mtd, + partition_handler_t handler, + FAR void *arg); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* CONFIG_DISABLE_MOUNTPOINT */ + +#endif /* __INCLUDE_NUTTX_FS_PARTITION_H */