Skip to content

Commit

Permalink
block: convert to bio_for_each_page_all also in __bio_unmap_user()
Browse files Browse the repository at this point in the history
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 <dongsu.park@profitbricks.com>
  • Loading branch information
Dongsu Park committed Dec 29, 2014
1 parent 25fdad5 commit 6347515
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions block/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1399,17 +1399,17 @@ struct bio *bio_map_user_iov(struct request_queue *q, struct block_device *bdev,

static void __bio_unmap_user(struct bio *bio)
{
struct bio_vec *bvec;
int i;
struct bio_vec bvec;
struct bvec_iter iter;

/*
* make sure we dirty pages we wrote to
*/
bio_for_each_segment_all(bvec, bio, i) {
bio_for_each_page_all(bvec, bio, iter) {
if (bio_data_dir(bio) == READ)
set_page_dirty_lock(bvec->bv_page);
set_page_dirty_lock(bvec.bv_page);

page_cache_release(bvec->bv_page);
page_cache_release(bvec.bv_page);
}

bio_put(bio);
Expand Down

0 comments on commit 6347515

Please sign in to comment.