This is an automated email from the ASF dual-hosted git repository.

ligd pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 23aef2d7b4804bc880f3663c405f13d5769dcc8d
Author: guohao15 <[email protected]>
AuthorDate: Thu Apr 25 18:37:56 2024 +0800

    romfs:extend romfs to enable write part3
    
    add romfs_mkfs to support autoformat && forceformat
    
    Signed-off-by: guohao15 <[email protected]>
---
 fs/romfs/fs_romfs.c     |  47 ++++++++++++----
 fs/romfs/fs_romfs.h     |   2 +
 fs/romfs/fs_romfsutil.c | 142 ++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 171 insertions(+), 20 deletions(-)

diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c
index 4797f7b2cd..3cbcddf287 100644
--- a/fs/romfs/fs_romfs.c
+++ b/fs/romfs/fs_romfs.c
@@ -1124,6 +1124,18 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR 
const void *data,
       goto errout_with_mount;
     }
 
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+  if (data && strstr(data, "rw") && strstr(data, "forceformat"))
+    {
+      ret = romfs_mkfs(rm);
+      if (ret < 0)
+        {
+          ferr("ERROR: romfs_mkfs failed: %d\n", ret);
+          goto errout_with_buffer;
+        }
+    }
+#endif
+
   /* Then complete the mount by getting the ROMFS configuratrion from
    * the ROMF header
    */
@@ -1131,8 +1143,29 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR 
const void *data,
   ret = romfs_fsconfigure(rm, data);
   if (ret < 0)
     {
-      ferr("ERROR: romfs_fsconfigure failed: %d\n", ret);
-      goto errout_with_buffer;
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+      if (data && strstr(data, "rw") && strstr(data, "autoformat"))
+        {
+          ret = romfs_mkfs(rm);
+          if (ret < 0)
+            {
+              ferr("ERROR: romfs_format failed: %d\n", ret);
+              goto errout_with_buffer;
+            }
+
+          ret = romfs_fsconfigure(rm, data);
+          if (ret < 0)
+            {
+              ferr("ERROR: romfs_fsconfigure failed: %d\n", ret);
+              goto errout_with_buffer;
+            }
+        }
+      else
+#endif
+        {
+          ferr("ERROR: romfs_fsconfigure failed: %d\n", ret);
+          goto errout_with_buffer;
+        }
     }
 
   /* Mounted! */
@@ -1141,10 +1174,7 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR 
const void *data,
   return OK;
 
 errout_with_buffer:
-  if (!rm->rm_xipbase)
-    {
-      fs_heap_free(rm->rm_buffer);
-    }
+  fs_heap_free(rm->rm_devbuffer);
 
 errout_with_mount:
   nxrmutex_destroy(&rm->rm_lock);
@@ -1231,10 +1261,7 @@ static int romfs_unbind(FAR void *handle, FAR struct 
inode **blkdriver,
 
       /* Release the mountpoint private data */
 
-      if (!rm->rm_xipbase)
-        {
-          fs_heap_free(rm->rm_buffer);
-        }
+      fs_heap_free(rm->rm_devbuffer);
 
 #ifdef CONFIG_FS_ROMFS_CACHE_NODE
       romfs_freenode(rm->rm_root);
diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h
index b066d0adf2..5906f68e83 100644
--- a/fs/romfs/fs_romfs.h
+++ b/fs/romfs/fs_romfs.h
@@ -154,6 +154,7 @@ struct romfs_mountpt_s
   uint32_t rm_cachesector;        /* Current sector in the rm_buffer */
   FAR uint8_t *rm_xipbase;        /* Base address of directly accessible media 
*/
   FAR uint8_t *rm_buffer;         /* Device sector buffer, allocated if 
rm_xipbase==0 */
+  FAR uint8_t *rm_devbuffer;      /* Device sector buffer, allocated for write 
if rm_xipbase != 0 */
 #ifdef CONFIG_FS_ROMFS_WRITEABLE
   struct list_node rm_sparelist;  /* The list of spare space */
 #endif
@@ -231,6 +232,7 @@ int  romfs_datastart(FAR struct romfs_mountpt_s *rm,
 void romfs_freenode(FAR struct romfs_nodeinfo_s *node);
 #endif
 #ifdef CONFIG_FS_ROMFS_WRITEABLE
+int romfs_mkfs(FAR struct romfs_mountpt_s *rm);
 void romfs_free_sparelist(FAR struct list_node *list);
 #endif
 
diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c
index a040e97385..c8d73dc786 100644
--- a/fs/romfs/fs_romfsutil.c
+++ b/fs/romfs/fs_romfsutil.c
@@ -408,7 +408,7 @@ static FAR struct romfs_sparenode_s *
 romfs_alloc_sparenode(uint32_t start, uint32_t end)
 {
   FAR struct romfs_sparenode_s *node;
-  node = kmm_malloc(sizeof(struct romfs_sparenode_s));
+  node = fs_heap_malloc(sizeof(struct romfs_sparenode_s));
   if (node == NULL)
     {
       ferr("romfs_alloc_sparenode: no memory\n");
@@ -474,7 +474,7 @@ static int romfs_alloc_spareregion(FAR struct list_node 
*list,
           /* Delete the node */
 
           list_delete(&node->node);
-          kmm_free(node);
+          fs_heap_free(node);
           return 0;
         }
       else if (start == node->start)
@@ -514,6 +514,78 @@ static int romfs_alloc_spareregion(FAR struct list_node 
*list,
         end);
   return -ENOENT;
 }
+
+/****************************************************************************
+ * Name: romfs_devwrite32
+ *
+ * Description:
+ *   Write the big-endian 32-bit value to the mount device buffer
+ *
+ ****************************************************************************/
+
+static void romfs_devwrite32(FAR struct romfs_mountpt_s *rm,
+                             int ndx, uint32_t value)
+{
+  /* Write the 32-bit value to the specified index in the buffer */
+
+  rm->rm_devbuffer[ndx]     = (uint8_t)(value >> 24) & 0xff;
+  rm->rm_devbuffer[ndx + 1] = (uint8_t)(value >> 16) & 0xff;
+  rm->rm_devbuffer[ndx + 2] = (uint8_t)(value >> 8) & 0xff;
+  rm->rm_devbuffer[ndx + 3] = (uint8_t)(value & 0xff);
+}
+
+/****************************************************************************
+ * Name: romfs_hwwrite
+ *
+ * Description:
+ *   Write the specified number of sectors to the block device
+ *
+ ****************************************************************************/
+
+static int romfs_hwwrite(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer,
+                         uint32_t sector, unsigned int nsectors)
+{
+  FAR struct inode *inode = rm->rm_blkdriver;
+  ssize_t ret = -ENODEV;
+
+  if (inode->u.i_bops->write)
+    {
+      ret = inode->u.i_bops->write(inode, buffer, sector, nsectors);
+    }
+
+  if (ret == (ssize_t)nsectors)
+    {
+      ret = OK;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: romfs_devcachewrite
+ *
+ * Description:
+ *   Write the specified sector for specified offset into the sector cache.
+ *
+ ****************************************************************************/
+
+static int romfs_devcachewrite(FAR struct romfs_mountpt_s *rm,
+                               uint32_t sector)
+{
+  int ret;
+
+  ret = romfs_hwwrite(rm, rm->rm_devbuffer, sector, 1);
+  if (ret == OK)
+    {
+      rm->rm_cachesector = sector;
+    }
+  else
+    {
+      rm->rm_cachesector = (uint32_t)-1;
+    }
+
+  return ret;
+}
 #endif
 
 /****************************************************************************
@@ -800,6 +872,14 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm)
 
   rm->rm_cachesector = (uint32_t)-1;
 
+  /* Allocate the device cache buffer for normal sector accesses */
+
+  rm->rm_devbuffer = fs_heap_malloc(rm->rm_hwsectorsize);
+  if (!rm->rm_devbuffer)
+    {
+      return -ENOMEM;
+    }
+
   if (inode->u.i_bops->ioctl)
     {
       ret = inode->u.i_bops->ioctl(inode, BIOC_XIPBASE,
@@ -816,14 +896,9 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm)
         }
     }
 
-  /* Allocate the device cache buffer for normal sector accesses */
-
-  rm->rm_buffer = fs_heap_malloc(rm->rm_hwsectorsize);
-  if (!rm->rm_buffer)
-    {
-      return -ENOMEM;
-    }
+  /* The device cache buffer for normal sector accesses */
 
+  rm->rm_buffer = rm->rm_devbuffer;
   return OK;
 }
 
@@ -843,7 +918,7 @@ void romfs_free_sparelist(FAR struct list_node *list)
   list_for_every_entry_safe(list, node, tmp, struct romfs_sparenode_s, node)
     {
       list_delete(&node->node);
-      kmm_free(node);
+      fs_heap_free(node);
     }
 }
 #endif
@@ -1343,3 +1418,50 @@ int romfs_datastart(FAR struct romfs_mountpt_s *rm,
   return -EINVAL; /* Won't get here */
 #endif
 }
+
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+
+/****************************************************************************
+ * Name: romfs_mkfs
+ *
+ * Description:
+ *   Format the romfs filesystem
+ *
+ ****************************************************************************/
+
+int romfs_mkfs(FAR struct romfs_mountpt_s *rm)
+{
+  /* Write the magic number at that identifies this as a ROMFS filesystem */
+
+  memcpy(rm->rm_devbuffer + ROMFS_VHDR_ROM1FS, ROMFS_VHDR_MAGIC,
+         ROMFS_VHDR_SIZE);
+
+  /* Init the ROMFS volume to zero */
+
+  romfs_devwrite32(rm, ROMFS_VHDR_SIZE, 0);
+
+  /* Write the volume name */
+
+  memcpy(rm->rm_devbuffer + ROMFS_VHDR_VOLNAME, "romfs", 6);
+
+  /* Write the root node . */
+
+  romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_NEXT, 0x40 | RFNEXT_DIRECTORY);
+  romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_INFO, 0x20);
+  romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_SIZE, 0);
+  romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_CHKSUM, 0);
+  memcpy(rm->rm_devbuffer + 0x20 + ROMFS_FHDR_NAME, ".", 2);
+
+  /* Write the root node .. */
+
+  romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_NEXT, RFNEXT_HARDLINK);
+  romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_INFO, 0x20);
+  romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_SIZE, 0);
+  romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_CHKSUM, 0);
+  memcpy(rm->rm_devbuffer + 0x40 + ROMFS_FHDR_NAME, "..", 3);
+
+  /* Write the buffer to sector zero */
+
+  return romfs_devcachewrite(rm, 0);
+}
+#endif

Reply via email to