From 38f0056dcdb1466561d634c137a67100b7f9f3a7 Mon Sep 17 00:00:00 2001 From: guohao15 Date: Mon, 29 Jul 2024 17:38:57 +0800 Subject: [PATCH] romfs:extend romfs to enable write part4 add sem for write safe Signed-off-by: guohao15 --- 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 2622cd70c84c5..3bf433435fce6 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 5906f68e837b8..92fe4dc7b2ff6 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 };