From owner-svn-src-head@freebsd.org Thu Nov 17 20:32:33 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 41C27C4778D; Thu, 17 Nov 2016 20:32:33 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1EA281DF2; Thu, 17 Nov 2016 20:32:33 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uAHKWWNw000440; Thu, 17 Nov 2016 20:32:32 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uAHKWWcT000439; Thu, 17 Nov 2016 20:32:32 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201611172032.uAHKWWcT000439@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Thu, 17 Nov 2016 20:32:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r308778 - head/sys/vm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Nov 2016 20:32:33 -0000 Author: glebius Date: Thu Nov 17 20:32:32 2016 New Revision: 308778 URL: https://svnweb.freebsd.org/changeset/base/308778 Log: - If caller specifies readbehind and readahead that together with count doesn't fit into a buf, then trim readbehind and readahead evenly. If rbehind was limited by the previous BMAP, then roundup its trim to block size. - Add KASSERT to check that b_blkno has proper offset from original blkno returned by BMAP. [1] - Add KASSERT to check that pages in buf are consecutive. Reviewed by: kib Submitted by: kib [1] Modified: head/sys/vm/vnode_pager.c Modified: head/sys/vm/vnode_pager.c ============================================================================== --- head/sys/vm/vnode_pager.c Thu Nov 17 20:00:20 2016 (r308777) +++ head/sys/vm/vnode_pager.c Thu Nov 17 20:32:32 2016 (r308778) @@ -743,6 +743,9 @@ vnode_pager_generic_getpages(struct vnod struct bufobj *bo; struct buf *bp; off_t foff; +#ifdef INVARIANTS + off_t blkno0; +#endif int bsize, pagesperblock, *freecnt; int error, before, after, rbehind, rahead, poff, i; int bytecount, secmask; @@ -843,6 +846,9 @@ vnode_pager_generic_getpages(struct vnod return (VM_PAGER_OK); } +#ifdef INVARIANTS + blkno0 = bp->b_blkno; +#endif bp->b_blkno += (foff % bsize) / DEV_BSIZE; /* Recalculate blocks available after/before to pages. */ @@ -864,7 +870,25 @@ vnode_pager_generic_getpages(struct vnod rbehind = min(rbehind, m[0]->pindex); rahead = min(rahead, after); rahead = min(rahead, object->size - m[count - 1]->pindex); - KASSERT(rbehind + rahead + count <= sizeof(bp->b_pages), + /* + * Check that total amount of pages fit into buf. Trim rbehind and + * rahead evenly if not. + */ + if (rbehind + rahead + count > nitems(bp->b_pages)) { + int trim, sum; + + trim = rbehind + rahead + count - nitems(bp->b_pages) + 1; + sum = rbehind + rahead; + if (rbehind == before) { + /* Roundup rbehind trim to block size. */ + rbehind -= roundup(trim * rbehind / sum, pagesperblock); + if (rbehind < 0) + rbehind = 0; + } else + rbehind -= trim * rbehind / sum; + rahead -= trim * rahead / sum; + } + KASSERT(rbehind + rahead + count <= nitems(bp->b_pages), ("%s: behind %d ahead %d count %d", __func__, rbehind, rahead, count)); @@ -947,8 +971,14 @@ vnode_pager_generic_getpages(struct vnod if (a_rahead) *a_rahead = bp->b_pgafter; +#ifdef INVARIANTS KASSERT(bp->b_npages <= nitems(bp->b_pages), ("%s: buf %p overflowed", __func__, bp)); + for (int j = 1; j < bp->b_npages; j++) + KASSERT(bp->b_pages[j]->pindex - 1 == + bp->b_pages[j - 1]->pindex, + ("%s: pages array not consecutive, bp %p", __func__, bp)); +#endif /* * Recalculate first offset and bytecount with regards to read behind. @@ -987,6 +1017,13 @@ vnode_pager_generic_getpages(struct vnod bp->b_vp = vp; bp->b_bcount = bp->b_bufsize = bp->b_runningbufspace = bytecount; bp->b_iooffset = dbtob(bp->b_blkno); + KASSERT(IDX_TO_OFF(m[0]->pindex - bp->b_pages[0]->pindex) == + (blkno0 - bp->b_blkno) * DEV_BSIZE + + IDX_TO_OFF(m[0]->pindex) % bsize, + ("wrong offsets bsize %d m[0] %ju b_pages[0] %ju " + "blkno0 %ju b_blkno %ju", bsize, + (uintmax_t)m[0]->pindex, (uintmax_t)bp->b_pages[0]->pindex, + (uintmax_t)blkno0, (uintmax_t)bp->b_blkno)); atomic_add_long(&runningbufspace, bp->b_runningbufspace); PCPU_INC(cnt.v_vnodein);