summaryrefslogtreecommitdiff
path: root/fs/pstore/platform.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-04-28 01:53:21 +0300
committerKees Cook <keescook@chromium.org>2017-04-28 06:35:34 +0300
commit3a7d2fd16c57a1ef47dc2891171514231c9c7c6e (patch)
tree89837e53f2b86e76275eeca582bdfe68dacc97e5 /fs/pstore/platform.c
parent041939c1ec54208b42f5cd819209173d52a29d34 (diff)
downloadlinux-3a7d2fd16c57a1ef47dc2891171514231c9c7c6e.tar.xz
pstore: Solve lockdep warning by moving inode locks
Lockdep complains about a possible deadlock between mount and unlink (which is technically impossible), but fixing this improves possible future multiple-backend support, and keeps locking in the right order. The lockdep warning could be triggered by unlinking a file in the pstore filesystem: -> #1 (&sb->s_type->i_mutex_key#14){++++++}: lock_acquire+0xc9/0x220 down_write+0x3f/0x70 pstore_mkfile+0x1f4/0x460 pstore_get_records+0x17a/0x320 pstore_fill_super+0xa4/0xc0 mount_single+0x89/0xb0 pstore_mount+0x13/0x20 mount_fs+0xf/0x90 vfs_kern_mount+0x66/0x170 do_mount+0x190/0xd50 SyS_mount+0x90/0xd0 entry_SYSCALL_64_fastpath+0x1c/0xb1 -> #0 (&psinfo->read_mutex){+.+.+.}: __lock_acquire+0x1ac0/0x1bb0 lock_acquire+0xc9/0x220 __mutex_lock+0x6e/0x990 mutex_lock_nested+0x16/0x20 pstore_unlink+0x3f/0xa0 vfs_unlink+0xb5/0x190 do_unlinkat+0x24c/0x2a0 SyS_unlinkat+0x16/0x30 entry_SYSCALL_64_fastpath+0x1c/0xb1 Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&sb->s_type->i_mutex_key#14); lock(&psinfo->read_mutex); lock(&sb->s_type->i_mutex_key#14); lock(&psinfo->read_mutex); Reported-by: Marta Lofstedt <marta.lofstedt@intel.com> Reported-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'fs/pstore/platform.c')
-rw-r--r--fs/pstore/platform.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 43b3ca5e045f..d468eec9b8a6 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -810,17 +810,17 @@ static void decompress_record(struct pstore_record *record)
}
/*
- * Read all the records from the persistent store. Create
+ * Read all the records from one persistent store backend. Create
* files in our filesystem. Don't warn about -EEXIST errors
* when we are re-scanning the backing store looking to add new
* error records.
*/
-void pstore_get_records(int quiet)
+void pstore_get_backend_records(struct pstore_info *psi,
+ struct dentry *root, int quiet)
{
- struct pstore_info *psi = psinfo;
int failed = 0;
- if (!psi)
+ if (!psi || !root)
return;
mutex_lock(&psi->read_mutex);
@@ -850,7 +850,7 @@ void pstore_get_records(int quiet)
break;
decompress_record(record);
- rc = pstore_mkfile(record);
+ rc = pstore_mkfile(root, record);
if (rc) {
/* pstore_mkfile() did not take record, so free it. */
kfree(record->buf);