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 38f0056dcdb1466561d634c137a67100b7f9f3a7
Author: guohao15 <[email protected]>
AuthorDate: Mon Jul 29 17:38:57 2024 +0800

    romfs:extend romfs to enable write part4
    
    add sem for write safe
    
    Signed-off-by: guohao15 <[email protected]>
---
 fs/romfs/fs_romfs.c | 71 ++++++++++++++++++++++++++++++++++++++++++++---------
 fs/romfs/fs_romfs.h |  1 +
 2 files changed, 61 insertions(+), 11 deletions(-)

diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c
index 2622cd70c8..3bf433435f 100644
--- a/fs/romfs/fs_romfs.c
+++ b/fs/romfs/fs_romfs.c
@@ -187,12 +187,22 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
       return ret;
     }
 
-  ret = romfs_checkmount(rm);
-  if (ret < 0)
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+  if (oflags & (O_WRONLY | O_APPEND | O_TRUNC | O_CREAT))
     {
-      ferr("ERROR: romfs_checkmount failed: %d\n", ret);
-      goto errout_with_lock;
+      if (list_is_empty(&rm->rm_sparelist))
+        {
+          ferr("ERROR: RW not enabled, only O_RDONLY supported\n");
+          ret = -EACCES;
+          goto errout_with_lock;
+        }
+
+      nxrmutex_unlock(&rm->rm_lock);
+      nxsem_wait_uninterruptible(&rm->rm_sem);
+      nxrmutex_lock(&rm->rm_lock);
     }
+  else
+#endif
 
   /* ROMFS is read-only.  Any attempt to open with any kind of write
    * access is not permitted.
@@ -205,6 +215,13 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
       goto errout_with_lock;
     }
 
+  ret = romfs_checkmount(rm);
+  if (ret < 0)
+    {
+      ferr("ERROR: romfs_checkmount failed: %d\n", ret);
+      goto errout_with_sem;
+    }
+
   /* Locate the directory entry for this path */
 
   ret = romfs_finddirentry(rm, &nodeinfo, relpath);
@@ -212,7 +229,7 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
     {
       ferr("ERROR: Failed to find directory directory entry for '%s': %d\n",
            relpath, ret);
-      goto errout_with_lock;
+      goto errout_with_sem;
     }
 
   /* The full path exists -- but is the final component a file
@@ -229,7 +246,7 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
 
       ret = -EISDIR;
       ferr("ERROR: '%s' is a directory\n", relpath);
-      goto errout_with_lock;
+      goto errout_with_sem;
     }
   else if (!IS_FILE(nodeinfo.rn_next))
     {
@@ -243,7 +260,7 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
 
       ret = -ENXIO;
       ferr("ERROR: '%s' is a special file\n", relpath);
-      goto errout_with_lock;
+      goto errout_with_sem;
     }
 
   /* Create an instance of the file private data to describe the opened
@@ -256,7 +273,7 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
     {
       ferr("ERROR: Failed to allocate private data\n");
       ret = -ENOMEM;
-      goto errout_with_lock;
+      goto errout_with_sem;
     }
 
   /* Initialize the file private data (only need to initialize
@@ -274,7 +291,7 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
     {
       ferr("ERROR: Failed to locate start of file data: %d\n", ret);
       fs_heap_free(rf);
-      goto errout_with_lock;
+      goto errout_with_sem;
     }
 
   /* Configure buffering to support access to this file */
@@ -284,15 +301,35 @@ static int romfs_open(FAR struct file *filep, FAR const 
char *relpath,
     {
       ferr("ERROR: Failed configure buffering: %d\n", ret);
       fs_heap_free(rf);
-      goto errout_with_lock;
+      goto errout_with_sem;
     }
 
   /* Attach the private date to the struct file instance */
 
   filep->f_priv = rf;
-
   rm->rm_refs++;
 
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+
+  /* If the file is only created for read */
+
+  if ((oflags & (O_WRONLY | O_APPEND | O_TRUNC | O_CREAT)) == O_CREAT)
+    {
+      nxsem_post(&rm->rm_sem);
+    }
+#endif
+
+  nxrmutex_unlock(&rm->rm_lock);
+  return ret;
+
+errout_with_sem:
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+  if (oflags & (O_WRONLY | O_APPEND | O_TRUNC | O_CREAT))
+    {
+      nxsem_post(&rm->rm_sem);
+    }
+#endif
+
 errout_with_lock:
   nxrmutex_unlock(&rm->rm_lock);
   return ret;
@@ -328,6 +365,13 @@ static int romfs_close(FAR struct file *filep)
     }
 
   rm->rm_refs--;
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+  if (filep->f_oflags & (O_WRONLY | O_APPEND | O_TRUNC))
+    {
+      nxsem_post(&rm->rm_sem);
+    }
+#endif
+
   nxrmutex_unlock(&rm->rm_lock);
 
   /* Do not check if the mount is healthy.  We must support closing of
@@ -1169,6 +1213,10 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR 
const void *data,
         }
     }
 
+#ifdef CONFIG_FS_ROMFS_WRITEABLE
+  nxsem_init(&rm->rm_sem, 0, 1);
+#endif
+
   /* Mounted! */
 
   *handle = rm;
@@ -1269,6 +1317,7 @@ static int romfs_unbind(FAR void *handle, FAR struct 
inode **blkdriver,
       romfs_freenode(rm->rm_root);
 #endif
 #ifdef CONFIG_FS_ROMFS_WRITEABLE
+      nxsem_destroy(&rm->rm_sem);
       romfs_free_sparelist(&rm->rm_sparelist);
 #endif
       nxrmutex_destroy(&rm->rm_lock);
diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h
index 5906f68e83..92fe4dc7b2 100644
--- a/fs/romfs/fs_romfs.h
+++ b/fs/romfs/fs_romfs.h
@@ -157,6 +157,7 @@ struct romfs_mountpt_s
   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 */
+  sem_t            rm_sem;        /* The semaphore to assume write safe */
 #endif
 };
 

Reply via email to