diff options
Diffstat (limited to 'fs/pstore/platform.c')
-rw-r--r-- | fs/pstore/platform.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index d0ce22237589..8c0076a1f896 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -69,8 +69,9 @@ static void pstore_dowork(struct work_struct *); static DECLARE_WORK(pstore_work, pstore_dowork); /* - * psinfo_lock just protects "psinfo" during - * calls to pstore_register() + * psinfo_lock protects "psinfo" during calls to + * pstore_register(), pstore_unregister(), and + * the filesystem mount/unmount routines. */ static DEFINE_MUTEX(psinfo_lock); struct pstore_info *psinfo; @@ -587,8 +588,6 @@ int pstore_register(struct pstore_info *psi) psinfo = psi; mutex_init(&psinfo->read_mutex); sema_init(&psinfo->buf_lock, 1); - mutex_unlock(&psinfo_lock); - if (psi->flags & PSTORE_FLAGS_DMESG) allocate_buf_for_compression(); @@ -620,12 +619,25 @@ int pstore_register(struct pstore_info *psi) pr_info("Registered %s as persistent store backend\n", psi->name); + mutex_unlock(&psinfo_lock); return 0; } EXPORT_SYMBOL_GPL(pstore_register); void pstore_unregister(struct pstore_info *psi) { + /* It's okay to unregister nothing. */ + if (!psi) + return; + + mutex_lock(&psinfo_lock); + + /* Only one backend can be registered at a time. */ + if (WARN_ON(psi != psinfo)) { + mutex_unlock(&psinfo_lock); + return; + } + /* Stop timer and make sure all work has finished. */ pstore_update_ms = -1; del_timer_sync(&pstore_timer); @@ -644,6 +656,7 @@ void pstore_unregister(struct pstore_info *psi) psinfo = NULL; backend = NULL; + mutex_unlock(&psinfo_lock); } EXPORT_SYMBOL_GPL(pstore_unregister); |