mirror of
https://github.com/apache/nuttx.git
synced 2026-05-19 20:06:24 +08:00
romfs:extend romfs to enable write part4
add sem for write safe Signed-off-by: guohao15 <guohao15@xiaomi.com>
This commit is contained in:
+60
-11
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user