projects
/
linux.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
9437e39
)
PM: hibernate: Get block device exclusively in swsusp_check()
author
Ye Bin
<yebin10@huawei.com>
Wed, 13 Oct 2021 12:19:14 +0000
(20:19 +0800)
committer
Rafael J. Wysocki
<rafael.j.wysocki@intel.com>
Thu, 21 Oct 2021 17:38:32 +0000
(19:38 +0200)
The following kernel crash can be triggered:
[ 89.266592] ------------[ cut here ]------------
[ 89.267427] kernel BUG at fs/buffer.c:3020!
[ 89.268264] invalid opcode: 0000 [#1] SMP KASAN PTI
[ 89.269116] CPU: 7 PID: 1750 Comm: kmmpd-loop0 Not tainted 5.10.0-862.14.0.6.x86_64
-08610-gc932cda3cef4
-dirty #20
[ 89.273169] RIP: 0010:submit_bh_wbc.isra.0+0x538/0x6d0
[ 89.277157] RSP: 0018:
ffff888105ddfd08
EFLAGS:
00010246
[ 89.278093] RAX:
0000000000000005
RBX:
ffff888124231498
RCX:
ffffffffb2772612
[ 89.279332] RDX:
1ffff11024846293
RSI:
0000000000000008
RDI:
ffff888124231498
[ 89.280591] RBP:
ffff8881248cc000
R08:
0000000000000001
R09:
ffffed1024846294
[ 89.281851] R10:
ffff88812423149f
R11:
ffffed1024846293
R12:
0000000000003800
[ 89.283095] R13:
0000000000000001
R14:
0000000000000000
R15:
ffff8881161f7000
[ 89.284342] FS:
0000000000000000
(0000) GS:
ffff88839b5c0000
(0000) knlGS:
0000000000000000
[ 89.285711] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 89.286701] CR2:
00007f166ebc01a0
CR3:
0000000435c0e000
CR4:
00000000000006e0
[ 89.287919] DR0:
0000000000000000
DR1:
0000000000000000
DR2:
0000000000000000
[ 89.289138] DR3:
0000000000000000
DR6:
00000000fffe0ff0
DR7:
0000000000000400
[ 89.290368] Call Trace:
[ 89.290842] write_mmp_block+0x2ca/0x510
[ 89.292218] kmmpd+0x433/0x9a0
[ 89.294902] kthread+0x2dd/0x3e0
[ 89.296268] ret_from_fork+0x22/0x30
[ 89.296906] Modules linked in:
by running the following commands:
1. mkfs.ext4 -O mmp /dev/sda -b 1024
2. mount /dev/sda /home/test
3. echo "/dev/sda" > /sys/power/resume
That happens because swsusp_check() calls set_blocksize() on the
target partition which confuses the file system:
Thread1 Thread2
mount /dev/sda /home/test
get s_mmp_bh --> has mapped flag
start kmmpd thread
echo "/dev/sda" > /sys/power/resume
resume_store
software_resume
swsusp_check
set_blocksize
truncate_inode_pages_range
truncate_cleanup_page
block_invalidatepage
discard_buffer --> clean mapped flag
write_mmp_block
submit_bh
submit_bh_wbc
BUG_ON(!buffer_mapped(bh))
To address this issue, modify swsusp_check() to open the target block
device with exclusive access.
Signed-off-by: Ye Bin <yebin10@huawei.com>
[ rjw: Subject and changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
kernel/power/swap.c
patch
|
blob
|
history
diff --git
a/kernel/power/swap.c
b/kernel/power/swap.c
index d59420b8d5ff4e9d74008177a9cf67b7dba49a9c..ff326c2cb77bd76f8cef4d8ca0673b8fb1df0085 100644
(file)
--- a/
kernel/power/swap.c
+++ b/
kernel/power/swap.c
@@
-1515,9
+1515,10
@@
end:
int swsusp_check(void)
{
int error;
+ void *holder;
hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
- FMODE_READ
, NULL
);
+ FMODE_READ
| FMODE_EXCL, &holder
);
if (!IS_ERR(hib_resume_bdev)) {
set_blocksize(hib_resume_bdev, PAGE_SIZE);
clear_page(swsusp_header);
@@
-1539,7
+1540,7
@@
int swsusp_check(void)
put:
if (error)
- blkdev_put(hib_resume_bdev, FMODE_READ);
+ blkdev_put(hib_resume_bdev, FMODE_READ
| FMODE_EXCL
);
else
pr_debug("Image signature found, resuming\n");
} else {