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);
     }

Reply via email to