
From: Kees Cook <keescook@chromium.org> stable inclusion from stable-5.10 category: feature commit:db23491c77207ef6bec2b232238710de4755db6a issue: #I4919J -------------------------------- 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. Link: https://lore.kernel.org/lkml/20200506152114.50375-6-keescook@chromium.org/ Signed-off-by: Kees Cook <keescook@chromium.org> (cherry picked from commit db23491c77207ef6bec2b232238710de4755db6a) Signed-off-by: roger <kongzhengrong@huawei.com> --- 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 73a57fec03fb..d5760195a0ad 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -34,14 +34,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 { @@ -204,13 +203,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); } } @@ -309,12 +307,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 && @@ -323,7 +320,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; @@ -356,9 +353,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.17.1