This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit a6fdbc538b47f35bd49eacc6b37f71ff8470cdee Author: jingfei <jing...@xiaomi.com> AuthorDate: Wed Jun 4 15:47:18 2025 +0800 Revert "ftl: should pre-allocate eblock for car case" This reverts commit 20fcdcf905f279a9c4527be399a90590f458db1f. The reason is that the erase buffer isn't always used in most cases. Signed-off-by: jingfei <jing...@xiaomi.com> --- drivers/mtd/ftl.c | 56 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 3b0e0a29b75..51c0f63736c 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -216,19 +216,6 @@ static int ftl_open(FAR struct inode *inode) DEBUGASSERT(inode->i_private); dev = inode->i_private; - - if (dev->refs == 0) - { - /* Allocate one, in-memory erase block buffer */ - - dev->eblock = kmm_malloc(dev->geo.erasesize); - if (!dev->eblock) - { - ferr("ERROR: Failed to allocate an erase block buffer\n"); - return -ENOMEM; - } - } - dev->refs++; return OK; } @@ -251,20 +238,17 @@ static int ftl_close(FAR struct inode *inode) rwb_flush(&dev->rwb); #endif - if (--dev->refs == 0) + if (--dev->refs == 0 && dev->unlinked) { +#ifdef FTL_HAVE_RWBUFFER + rwb_uninitialize(&dev->rwb); +#endif if (dev->eblock) { kmm_free(dev->eblock); } - if (dev->unlinked) - { -#ifdef FTL_HAVE_RWBUFFER - rwb_uninitialize(&dev->rwb); -#endif - kmm_free(dev); - } + kmm_free(dev); } return OK; @@ -478,6 +462,18 @@ static ssize_t ftl_read(FAR struct inode *inode, unsigned char *buffer, * ****************************************************************************/ +static int ftl_alloc_eblock(FAR struct ftl_struct_s *dev) +{ + if (dev->eblock == NULL) + { + /* Allocate one, in-memory erase block buffer */ + + dev->eblock = kmm_malloc(dev->geo.erasesize); + } + + return dev->eblock != NULL ? OK : -ENOMEM; +} + static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, off_t startblock, size_t nblocks) { @@ -509,6 +505,13 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, bool short_write = (remaining < (alignedblock - startblock)); + ret = ftl_alloc_eblock(dev); + if (ret < 0) + { + ferr("ERROR: Failed to allocate an erase block buffer\n"); + return ret; + } + /* Read the full erase block into the buffer */ rwblock = startblock & ~mask; @@ -602,6 +605,13 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, if (remaining > 0) { + ret = ftl_alloc_eblock(dev); + if (ret < 0) + { + ferr("ERROR: Failed to allocate an erase block buffer\n"); + return ret; + } + /* Read the full erase block into the buffer */ nxfrd = ftl_mtd_bread(dev, alignedblock, dev->blkper, dev->eblock); @@ -765,6 +775,10 @@ static int ftl_unlink(FAR struct inode *inode) #ifdef FTL_HAVE_RWBUFFER rwb_uninitialize(&dev->rwb); #endif + if (dev->eblock) + { + kmm_free(dev->eblock); + } kmm_free(dev); }