Skip to content

Commit 399c460

Browse files
vtlgregkh
authored andcommitted
fix unbalanced page refcounting in bio_map_user_iov
commit 95d78c28b5a85bacbc29b8dba7c04babb9b0d467 upstream. bio_map_user_iov and bio_unmap_user do unbalanced pages refcounting if IO vector has small consecutive buffers belonging to the same page. bio_add_pc_page merges them into one, but the page reference is never dropped. Signed-off-by: Vitaly Mayatskikh <v.mayatskih@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f3b5384 commit 399c460

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

block/bio.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ struct bio *bio_map_user_iov(struct request_queue *q,
13201320
offset = uaddr & ~PAGE_MASK;
13211321
for (j = cur_page; j < page_limit; j++) {
13221322
unsigned int bytes = PAGE_SIZE - offset;
1323+
unsigned short prev_bi_vcnt = bio->bi_vcnt;
13231324

13241325
if (len <= 0)
13251326
break;
@@ -1334,6 +1335,13 @@ struct bio *bio_map_user_iov(struct request_queue *q,
13341335
bytes)
13351336
break;
13361337

1338+
/*
1339+
* check if vector was merged with previous
1340+
* drop page reference if needed
1341+
*/
1342+
if (bio->bi_vcnt == prev_bi_vcnt)
1343+
put_page(pages[j]);
1344+
13371345
len -= bytes;
13381346
offset = 0;
13391347
}

0 commit comments

Comments
 (0)