Skip to content

Commit 3019812

Browse files
author
Dongsu Park
committed
block: convert to bio_for_each_page_all also in __bio_unmap_user()
Replace bio_for_each_segment_all() with bio_for_each_page_all(), also in __bio_unmap_user(). Follow-up of commit 160e570ce. Without this fix, page_cache_release() sometimes causes kernel to crash like this: BUG: Bad page state in process kworker/1:7 pfn:74322 page:ffffea0001d0c880 count:0 mapcount:1 mapping: (null) index:0x7f0108bfb flags: page dumped because: nonzero mapcount CPU: 1 PID: 3795 Comm: kworker/1:7 Tainted: G W 3.19.0-rc1+ torvalds#87 Workqueue: events bio_dirty_fn ffffffff81c53428 ffff880077e5bbf8 ffffffff818004a6 ffff88007d1cf278 ffffea0001d0c880 ffff880077e5bc28 ffffffff811b114c ffff880077e5bc28 ffffea0001d0c880 ffffea0001d0c880 0000000000000000 ffff880077e5bc88 Call Trace: [<ffffffff818004a6>] dump_stack+0x4c/0x65 [<ffffffff811b114c>] bad_page.part.57+0xbc/0x110 [<ffffffff811b1d11>] free_pages_prepare+0x231/0x400 [<ffffffff811b47f5>] free_hot_cold_page+0x35/0x1b0 [<ffffffff811bc4b6>] ? __page_cache_release+0xf6/0x170 [<ffffffff811bd1ef>] put_page+0x3f/0x70 [<ffffffff814e5056>] bio_dirty_fn+0x76/0xa0 [<ffffffff8109bd88>] process_one_work+0x1e8/0x7f0 [<ffffffff8109bcfd>] ? process_one_work+0x15d/0x7f0 [<ffffffff8109c48b>] ? worker_thread+0xfb/0x4b0 [<ffffffff8109c3fb>] worker_thread+0x6b/0x4b0 [<ffffffff8109c390>] ? process_one_work+0x7f0/0x7f0 [<ffffffff810a232d>] kthread+0x10d/0x130 [<ffffffff810d509d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffff810a2220>] ? kthread_create_on_node+0x230/0x230 [<ffffffff8180a1ec>] ret_from_fork+0x7c/0xb0 [<ffffffff810a2220>] ? kthread_create_on_node+0x230/0x230 Signed-off-by: Dongsu Park <[email protected]>
1 parent ccb3cd2 commit 3019812

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

block/bio.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -1448,17 +1448,17 @@ struct bio *bio_map_user_iov(struct request_queue *q, struct block_device *bdev,
14481448

14491449
static void __bio_unmap_user(struct bio *bio)
14501450
{
1451-
struct bio_vec *bvec;
1452-
int i;
1451+
struct bio_vec bvec;
1452+
struct bvec_iter iter;
14531453

14541454
/*
14551455
* make sure we dirty pages we wrote to
14561456
*/
1457-
bio_for_each_segment_all(bvec, bio, i) {
1457+
bio_for_each_page_all(bvec, bio, iter) {
14581458
if (bio_data_dir(bio) == READ)
1459-
set_page_dirty_lock(bvec->bv_page);
1459+
set_page_dirty_lock(bvec.bv_page);
14601460

1461-
page_cache_release(bvec->bv_page);
1461+
page_cache_release(bvec.bv_page);
14621462
}
14631463

14641464
bio_put(bio);

0 commit comments

Comments
 (0)