The pstorefs internal list lock doesn't need to be a spinlock and will create problems when trying to access the list in the subsequent patch that will walk the pstorefs records during pstore_unregister(). Change this to a mutex to avoid may_sleep() warnings when unregistering devices.
Signed-off-by: Kees Cook <keesc...@chromium.org> --- fs/pstore/inode.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 5cc09cb315f9..92ebcc75434f 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -22,14 +22,13 @@ #include <linux/magic.h> #include <linux/pstore.h> #include <linux/slab.h> -#include <linux/spinlock.h> #include <linux/uaccess.h> #include "internal.h" #define PSTORE_NAMELEN 64 -static DEFINE_SPINLOCK(records_list_lock); +static DEFINE_MUTEX(records_list_lock); static LIST_HEAD(records_list); struct pstore_private { @@ -192,13 +191,12 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) static void pstore_evict_inode(struct inode *inode) { struct pstore_private *p = inode->i_private; - unsigned long flags; clear_inode(inode); if (p) { - spin_lock_irqsave(&records_list_lock, flags); + mutex_lock(&records_list_lock); list_del(&p->list); - spin_unlock_irqrestore(&records_list_lock, flags); + mutex_unlock(&records_list_lock); free_pstore_private(p); } } @@ -297,12 +295,11 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) int rc = 0; char name[PSTORE_NAMELEN]; struct pstore_private *private, *pos; - unsigned long flags; size_t size = record->size + record->ecc_notice_size; WARN_ON(!inode_is_locked(d_inode(root))); - spin_lock_irqsave(&records_list_lock, flags); + mutex_lock(&records_list_lock); list_for_each_entry(pos, &records_list, list) { if (pos->record->type == record->type && pos->record->id == record->id && @@ -311,7 +308,7 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) break; } } - spin_unlock_irqrestore(&records_list_lock, flags); + mutex_unlock(&records_list_lock); if (rc) return rc; @@ -343,9 +340,9 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) d_add(dentry, inode); - spin_lock_irqsave(&records_list_lock, flags); + mutex_lock(&records_list_lock); list_add(&private->list, &records_list); - spin_unlock_irqrestore(&records_list_lock, flags); + mutex_unlock(&records_list_lock); return 0; -- 2.20.1