From 84d313761d57ef1af243f4c8e72aa86e0fab6d1f Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Mon, 4 May 2015 18:49:25 +0000 Subject: [PATCH] Fix arithmetical bug in vnode_pager_haspage(). The check against object size should be done not with the number of pages in the first block, but with the overall number of pages. While here, add KASSERT that makes sure that BMAP doesn't return completely irrelevant blocks. Reviewed by: kib Tested by: pho Sponsored by: Netflix Sponsored by: Nginx, Inc. --- sys/vm/vnode_pager.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 2878dc3b0b9b..64601636072b 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -340,16 +340,21 @@ vnode_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before, *before += poff; } if (after) { - int numafter; + /* + * The BMAP vop can report a partial block in the + * 'after', but must not count blocks after EOF. + * Assert the latter, and truncate 'after' in case + * of the former. + */ + KASSERT(reqblock + *after <= + object->size * pagesperblock, + ("%s: reqblock %jd after %d size %ju", __func__, + (intmax_t )reqblock, *after, + (uintmax_t )object->size)); *after *= pagesperblock; - numafter = pagesperblock - (poff + 1); - if (IDX_TO_OFF(pindex + numafter) > - object->un_pager.vnp.vnp_size) { - numafter = - OFF_TO_IDX(object->un_pager.vnp.vnp_size) - - pindex; - } - *after += numafter; + *after += pagesperblock - (poff + 1); + if (pindex + *after >= object->size) + *after = object->size - 1 - pindex; } } else { if (before) {