31
31
static DEFINE_MUTEX (records_list_lock );
32
32
static LIST_HEAD (records_list );
33
33
34
+ static DEFINE_MUTEX (pstore_sb_lock );
35
+ static struct super_block * pstore_sb ;
36
+
34
37
struct pstore_private {
35
38
struct list_head list ;
36
39
struct pstore_record * record ;
@@ -282,11 +285,25 @@ static const struct super_operations pstore_ops = {
282
285
.show_options = pstore_show_options ,
283
286
};
284
287
285
- static struct super_block * pstore_sb ;
286
-
287
- bool pstore_is_mounted (void )
288
+ static struct dentry * psinfo_lock_root (void )
288
289
{
289
- return pstore_sb != NULL ;
290
+ struct dentry * root ;
291
+
292
+ mutex_lock (& pstore_sb_lock );
293
+ /*
294
+ * Having no backend is fine -- no records appear.
295
+ * Not being mounted is fine -- nothing to do.
296
+ */
297
+ if (!psinfo || !pstore_sb ) {
298
+ mutex_unlock (& pstore_sb_lock );
299
+ return NULL ;
300
+ }
301
+
302
+ root = pstore_sb -> s_root ;
303
+ inode_lock (d_inode (root ));
304
+ mutex_unlock (& pstore_sb_lock );
305
+
306
+ return root ;
290
307
}
291
308
292
309
/*
@@ -303,20 +320,18 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
303
320
struct pstore_private * private , * pos ;
304
321
size_t size = record -> size + record -> ecc_notice_size ;
305
322
306
- WARN_ON (!inode_is_locked (d_inode (root )));
323
+ if (WARN_ON (!inode_is_locked (d_inode (root ))))
324
+ return - EINVAL ;
307
325
326
+ rc = - EEXIST ;
327
+ /* Skip records that are already present in the filesystem. */
308
328
mutex_lock (& records_list_lock );
309
329
list_for_each_entry (pos , & records_list , list ) {
310
330
if (pos -> record -> type == record -> type &&
311
331
pos -> record -> id == record -> id &&
312
- pos -> record -> psi == record -> psi ) {
313
- rc = - EEXIST ;
314
- break ;
315
- }
332
+ pos -> record -> psi == record -> psi )
333
+ goto fail ;
316
334
}
317
- mutex_unlock (& records_list_lock );
318
- if (rc )
319
- return rc ;
320
335
321
336
rc = - ENOMEM ;
322
337
inode = pstore_get_inode (root -> d_sb );
@@ -346,7 +361,6 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
346
361
347
362
d_add (dentry , inode );
348
363
349
- mutex_lock (& records_list_lock );
350
364
list_add (& private -> list , & records_list );
351
365
mutex_unlock (& records_list_lock );
352
366
@@ -356,8 +370,8 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
356
370
free_pstore_private (private );
357
371
fail_inode :
358
372
iput (inode );
359
-
360
373
fail :
374
+ mutex_unlock (& records_list_lock );
361
375
return rc ;
362
376
}
363
377
@@ -369,25 +383,20 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
369
383
*/
370
384
void pstore_get_records (int quiet )
371
385
{
372
- struct pstore_info * psi = psinfo ;
373
386
struct dentry * root ;
374
387
375
- if (!psi || !pstore_sb )
388
+ root = psinfo_lock_root ();
389
+ if (!root )
376
390
return ;
377
391
378
- root = pstore_sb -> s_root ;
379
-
380
- inode_lock (d_inode (root ));
381
- pstore_get_backend_records (psi , root , quiet );
392
+ pstore_get_backend_records (psinfo , root , quiet );
382
393
inode_unlock (d_inode (root ));
383
394
}
384
395
385
396
static int pstore_fill_super (struct super_block * sb , void * data , int silent )
386
397
{
387
398
struct inode * inode ;
388
399
389
- pstore_sb = sb ;
390
-
391
400
sb -> s_maxbytes = MAX_LFS_FILESIZE ;
392
401
sb -> s_blocksize = PAGE_SIZE ;
393
402
sb -> s_blocksize_bits = PAGE_SHIFT ;
@@ -408,6 +417,10 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent)
408
417
if (!sb -> s_root )
409
418
return - ENOMEM ;
410
419
420
+ mutex_lock (& pstore_sb_lock );
421
+ pstore_sb = sb ;
422
+ mutex_unlock (& pstore_sb_lock );
423
+
411
424
pstore_get_records (0 );
412
425
413
426
return 0 ;
@@ -421,9 +434,17 @@ static struct dentry *pstore_mount(struct file_system_type *fs_type,
421
434
422
435
static void pstore_kill_sb (struct super_block * sb )
423
436
{
437
+ mutex_lock (& pstore_sb_lock );
438
+ WARN_ON (pstore_sb != sb );
439
+
424
440
kill_litter_super (sb );
425
441
pstore_sb = NULL ;
442
+
443
+ mutex_lock (& records_list_lock );
426
444
INIT_LIST_HEAD (& records_list );
445
+ mutex_unlock (& records_list_lock );
446
+
447
+ mutex_unlock (& pstore_sb_lock );
427
448
}
428
449
429
450
static struct file_system_type pstore_fs_type = {
0 commit comments