Skip to content

Commit fb32975

Browse files
ecashintorvalds
authored andcommitted
aoe: adjust ref of head for compound page tails
Fix a BUG which can trigger when direct-IO is used with AOE. As discussed previously, the fact that some users of the block layer provide bios that point to pages with a zero _count means that it is not OK for the network layer to do a put_page on the skb frags during an skb_linearize, so the aoe driver gets a reference to pages in bios and puts the reference before ending the bio. And because it cannot use get_page on a page with a zero _count, it manipulates the value directly. It is not OK to increment the _count of a compound page tail, though, since the VM layer will VM_BUG_ON a non-zero _count. Block users that do direct I/O can result in the aoe driver seeing compound page tails in bios. In that case, the same logic works as long as the head of the compound page is used instead of the tails. This patch handles compound pages and does not BUG. It relies on the block layer user leaving the relationship between the page tail and its head alone for the duration between the submission of the bio and its completion, whether successful or not. Signed-off-by: Ed Cashin <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent dfa9771 commit fb32975

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed

drivers/block/aoe/aoecmd.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -906,16 +906,10 @@ bio_pageinc(struct bio *bio)
906906
int i;
907907

908908
bio_for_each_segment(bv, bio, i) {
909-
page = bv->bv_page;
910909
/* Non-zero page count for non-head members of
911-
* compound pages is no longer allowed by the kernel,
912-
* but this has never been seen here.
910+
* compound pages is no longer allowed by the kernel.
913911
*/
914-
if (unlikely(PageCompound(page)))
915-
if (compound_trans_head(page) != page) {
916-
pr_crit("page tail used for block I/O\n");
917-
BUG();
918-
}
912+
page = compound_trans_head(bv->bv_page);
919913
atomic_inc(&page->_count);
920914
}
921915
}
@@ -924,10 +918,13 @@ static void
924918
bio_pagedec(struct bio *bio)
925919
{
926920
struct bio_vec *bv;
921+
struct page *page;
927922
int i;
928923

929-
bio_for_each_segment(bv, bio, i)
930-
atomic_dec(&bv->bv_page->_count);
924+
bio_for_each_segment(bv, bio, i) {
925+
page = compound_trans_head(bv->bv_page);
926+
atomic_dec(&page->_count);
927+
}
931928
}
932929

933930
static void

0 commit comments

Comments
 (0)