Skip to content

Commit 38f0056

Browse files
guohao15GUIDINGLI
authored andcommitted
romfs:extend romfs to enable write part4
add sem for write safe Signed-off-by: guohao15 <[email protected]>
1 parent 322765b commit 38f0056

File tree

2 files changed

+61
-11
lines changed

2 files changed

+61
-11
lines changed

fs/romfs/fs_romfs.c

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,22 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
187187
return ret;
188188
}
189189

190-
ret = romfs_checkmount(rm);
191-
if (ret < 0)
190+
#ifdef CONFIG_FS_ROMFS_WRITEABLE
191+
if (oflags & (O_WRONLY | O_APPEND | O_TRUNC | O_CREAT))
192192
{
193-
ferr("ERROR: romfs_checkmount failed: %d\n", ret);
194-
goto errout_with_lock;
193+
if (list_is_empty(&rm->rm_sparelist))
194+
{
195+
ferr("ERROR: RW not enabled, only O_RDONLY supported\n");
196+
ret = -EACCES;
197+
goto errout_with_lock;
198+
}
199+
200+
nxrmutex_unlock(&rm->rm_lock);
201+
nxsem_wait_uninterruptible(&rm->rm_sem);
202+
nxrmutex_lock(&rm->rm_lock);
195203
}
204+
else
205+
#endif
196206

197207
/* ROMFS is read-only. Any attempt to open with any kind of write
198208
* access is not permitted.
@@ -205,14 +215,21 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
205215
goto errout_with_lock;
206216
}
207217

218+
ret = romfs_checkmount(rm);
219+
if (ret < 0)
220+
{
221+
ferr("ERROR: romfs_checkmount failed: %d\n", ret);
222+
goto errout_with_sem;
223+
}
224+
208225
/* Locate the directory entry for this path */
209226

210227
ret = romfs_finddirentry(rm, &nodeinfo, relpath);
211228
if (ret < 0)
212229
{
213230
ferr("ERROR: Failed to find directory directory entry for '%s': %d\n",
214231
relpath, ret);
215-
goto errout_with_lock;
232+
goto errout_with_sem;
216233
}
217234

218235
/* 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,
229246

230247
ret = -EISDIR;
231248
ferr("ERROR: '%s' is a directory\n", relpath);
232-
goto errout_with_lock;
249+
goto errout_with_sem;
233250
}
234251
else if (!IS_FILE(nodeinfo.rn_next))
235252
{
@@ -243,7 +260,7 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
243260

244261
ret = -ENXIO;
245262
ferr("ERROR: '%s' is a special file\n", relpath);
246-
goto errout_with_lock;
263+
goto errout_with_sem;
247264
}
248265

249266
/* 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,
256273
{
257274
ferr("ERROR: Failed to allocate private data\n");
258275
ret = -ENOMEM;
259-
goto errout_with_lock;
276+
goto errout_with_sem;
260277
}
261278

262279
/* 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,
274291
{
275292
ferr("ERROR: Failed to locate start of file data: %d\n", ret);
276293
fs_heap_free(rf);
277-
goto errout_with_lock;
294+
goto errout_with_sem;
278295
}
279296

280297
/* Configure buffering to support access to this file */
@@ -284,15 +301,35 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
284301
{
285302
ferr("ERROR: Failed configure buffering: %d\n", ret);
286303
fs_heap_free(rf);
287-
goto errout_with_lock;
304+
goto errout_with_sem;
288305
}
289306

290307
/* Attach the private date to the struct file instance */
291308

292309
filep->f_priv = rf;
293-
294310
rm->rm_refs++;
295311

312+
#ifdef CONFIG_FS_ROMFS_WRITEABLE
313+
314+
/* If the file is only created for read */
315+
316+
if ((oflags & (O_WRONLY | O_APPEND | O_TRUNC | O_CREAT)) == O_CREAT)
317+
{
318+
nxsem_post(&rm->rm_sem);
319+
}
320+
#endif
321+
322+
nxrmutex_unlock(&rm->rm_lock);
323+
return ret;
324+
325+
errout_with_sem:
326+
#ifdef CONFIG_FS_ROMFS_WRITEABLE
327+
if (oflags & (O_WRONLY | O_APPEND | O_TRUNC | O_CREAT))
328+
{
329+
nxsem_post(&rm->rm_sem);
330+
}
331+
#endif
332+
296333
errout_with_lock:
297334
nxrmutex_unlock(&rm->rm_lock);
298335
return ret;
@@ -328,6 +365,13 @@ static int romfs_close(FAR struct file *filep)
328365
}
329366

330367
rm->rm_refs--;
368+
#ifdef CONFIG_FS_ROMFS_WRITEABLE
369+
if (filep->f_oflags & (O_WRONLY | O_APPEND | O_TRUNC))
370+
{
371+
nxsem_post(&rm->rm_sem);
372+
}
373+
#endif
374+
331375
nxrmutex_unlock(&rm->rm_lock);
332376

333377
/* 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,
11691213
}
11701214
}
11711215

1216+
#ifdef CONFIG_FS_ROMFS_WRITEABLE
1217+
nxsem_init(&rm->rm_sem, 0, 1);
1218+
#endif
1219+
11721220
/* Mounted! */
11731221

11741222
*handle = rm;
@@ -1269,6 +1317,7 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
12691317
romfs_freenode(rm->rm_root);
12701318
#endif
12711319
#ifdef CONFIG_FS_ROMFS_WRITEABLE
1320+
nxsem_destroy(&rm->rm_sem);
12721321
romfs_free_sparelist(&rm->rm_sparelist);
12731322
#endif
12741323
nxrmutex_destroy(&rm->rm_lock);

fs/romfs/fs_romfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ struct romfs_mountpt_s
157157
FAR uint8_t *rm_devbuffer; /* Device sector buffer, allocated for write if rm_xipbase != 0 */
158158
#ifdef CONFIG_FS_ROMFS_WRITEABLE
159159
struct list_node rm_sparelist; /* The list of spare space */
160+
sem_t rm_sem; /* The semaphore to assume write safe */
160161
#endif
161162
};
162163

0 commit comments

Comments
 (0)