@@ -187,12 +187,22 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
187
187
return ret ;
188
188
}
189
189
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 ) )
192
192
{
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 );
195
203
}
204
+ else
205
+ #endif
196
206
197
207
/* ROMFS is read-only. Any attempt to open with any kind of write
198
208
* access is not permitted.
@@ -205,14 +215,21 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
205
215
goto errout_with_lock ;
206
216
}
207
217
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
+
208
225
/* Locate the directory entry for this path */
209
226
210
227
ret = romfs_finddirentry (rm , & nodeinfo , relpath );
211
228
if (ret < 0 )
212
229
{
213
230
ferr ("ERROR: Failed to find directory directory entry for '%s': %d\n" ,
214
231
relpath , ret );
215
- goto errout_with_lock ;
232
+ goto errout_with_sem ;
216
233
}
217
234
218
235
/* 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,
229
246
230
247
ret = - EISDIR ;
231
248
ferr ("ERROR: '%s' is a directory\n" , relpath );
232
- goto errout_with_lock ;
249
+ goto errout_with_sem ;
233
250
}
234
251
else if (!IS_FILE (nodeinfo .rn_next ))
235
252
{
@@ -243,7 +260,7 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
243
260
244
261
ret = - ENXIO ;
245
262
ferr ("ERROR: '%s' is a special file\n" , relpath );
246
- goto errout_with_lock ;
263
+ goto errout_with_sem ;
247
264
}
248
265
249
266
/* 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,
256
273
{
257
274
ferr ("ERROR: Failed to allocate private data\n" );
258
275
ret = - ENOMEM ;
259
- goto errout_with_lock ;
276
+ goto errout_with_sem ;
260
277
}
261
278
262
279
/* 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,
274
291
{
275
292
ferr ("ERROR: Failed to locate start of file data: %d\n" , ret );
276
293
fs_heap_free (rf );
277
- goto errout_with_lock ;
294
+ goto errout_with_sem ;
278
295
}
279
296
280
297
/* Configure buffering to support access to this file */
@@ -284,15 +301,35 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
284
301
{
285
302
ferr ("ERROR: Failed configure buffering: %d\n" , ret );
286
303
fs_heap_free (rf );
287
- goto errout_with_lock ;
304
+ goto errout_with_sem ;
288
305
}
289
306
290
307
/* Attach the private date to the struct file instance */
291
308
292
309
filep -> f_priv = rf ;
293
-
294
310
rm -> rm_refs ++ ;
295
311
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
+
296
333
errout_with_lock :
297
334
nxrmutex_unlock (& rm -> rm_lock );
298
335
return ret ;
@@ -328,6 +365,13 @@ static int romfs_close(FAR struct file *filep)
328
365
}
329
366
330
367
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
+
331
375
nxrmutex_unlock (& rm -> rm_lock );
332
376
333
377
/* 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,
1169
1213
}
1170
1214
}
1171
1215
1216
+ #ifdef CONFIG_FS_ROMFS_WRITEABLE
1217
+ nxsem_init (& rm -> rm_sem , 0 , 1 );
1218
+ #endif
1219
+
1172
1220
/* Mounted! */
1173
1221
1174
1222
* handle = rm ;
@@ -1269,6 +1317,7 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
1269
1317
romfs_freenode (rm -> rm_root );
1270
1318
#endif
1271
1319
#ifdef CONFIG_FS_ROMFS_WRITEABLE
1320
+ nxsem_destroy (& rm -> rm_sem );
1272
1321
romfs_free_sparelist (& rm -> rm_sparelist );
1273
1322
#endif
1274
1323
nxrmutex_destroy (& rm -> rm_lock );
0 commit comments