diff options
author | Kees Cook <keescook@chromium.org> | 2017-04-28 01:53:21 +0300 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2017-04-28 06:35:34 +0300 |
commit | 3a7d2fd16c57a1ef47dc2891171514231c9c7c6e (patch) | |
tree | 89837e53f2b86e76275eeca582bdfe68dacc97e5 /fs/pstore/platform.c | |
parent | 041939c1ec54208b42f5cd819209173d52a29d34 (diff) | |
download | linux-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.c | 10 |
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); |