@@ -69,8 +69,9 @@ static void pstore_dowork(struct work_struct *);
69
69
static DECLARE_WORK (pstore_work , pstore_dowork ) ;
70
70
71
71
/*
72
- * psinfo_lock just protects "psinfo" during
73
- * calls to pstore_register()
72
+ * psinfo_lock protects "psinfo" during calls to
73
+ * pstore_register(), pstore_unregister(), and
74
+ * the filesystem mount/unmount routines.
74
75
*/
75
76
static DEFINE_MUTEX (psinfo_lock );
76
77
struct pstore_info * psinfo ;
@@ -587,8 +588,6 @@ int pstore_register(struct pstore_info *psi)
587
588
psinfo = psi ;
588
589
mutex_init (& psinfo -> read_mutex );
589
590
sema_init (& psinfo -> buf_lock , 1 );
590
- mutex_unlock (& psinfo_lock );
591
-
592
591
593
592
if (psi -> flags & PSTORE_FLAGS_DMESG )
594
593
allocate_buf_for_compression ();
@@ -620,12 +619,25 @@ int pstore_register(struct pstore_info *psi)
620
619
621
620
pr_info ("Registered %s as persistent store backend\n" , psi -> name );
622
621
622
+ mutex_unlock (& psinfo_lock );
623
623
return 0 ;
624
624
}
625
625
EXPORT_SYMBOL_GPL (pstore_register );
626
626
627
627
void pstore_unregister (struct pstore_info * psi )
628
628
{
629
+ /* It's okay to unregister nothing. */
630
+ if (!psi )
631
+ return ;
632
+
633
+ mutex_lock (& psinfo_lock );
634
+
635
+ /* Only one backend can be registered at a time. */
636
+ if (WARN_ON (psi != psinfo )) {
637
+ mutex_unlock (& psinfo_lock );
638
+ return ;
639
+ }
640
+
629
641
/* Stop timer and make sure all work has finished. */
630
642
pstore_update_ms = -1 ;
631
643
del_timer_sync (& pstore_timer );
@@ -644,6 +656,7 @@ void pstore_unregister(struct pstore_info *psi)
644
656
645
657
psinfo = NULL ;
646
658
backend = NULL ;
659
+ mutex_unlock (& psinfo_lock );
647
660
}
648
661
EXPORT_SYMBOL_GPL (pstore_unregister );
649
662
0 commit comments