Skip to content

Commit

Permalink
romfs:extend romfs to enable write part4
Browse files Browse the repository at this point in the history
add sem for write safe

Signed-off-by: guohao15 <[email protected]>
  • Loading branch information
guohao15 authored and GUIDINGLI committed Oct 11, 2024
1 parent 322765b commit 38f0056
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 11 deletions.
71 changes: 60 additions & 11 deletions fs/romfs/fs_romfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -205,14 +215,21 @@ 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);
if (ret < 0)
{
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
Expand All @@ -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))
{
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 */
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions fs/romfs/fs_romfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down

0 comments on commit 38f0056

Please sign in to comment.