From owner-freebsd-fs@freebsd.org Mon Oct 3 17:49:16 2016 Return-Path: Delivered-To: freebsd-fs@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 AE933AF4350 for ; Mon, 3 Oct 2016 17:49:16 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3FF36BE9 for ; Mon, 3 Oct 2016 17:49:16 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kib@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id u93Hn2wi093769 (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Mon, 3 Oct 2016 20:49:02 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua u93Hn2wi093769 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id u93Hn24F093768; Mon, 3 Oct 2016 20:49:02 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Mon, 3 Oct 2016 20:49:02 +0300 From: Konstantin Belousov To: Anton Yuzhaninov Cc: "freebsd-fs@freebsd.org" Subject: Re: UFS: unaligned read from GELI with 8k sectorsize Message-ID: <20161003174902.GR38409@kib.kiev.ua> References: <20161001114536.GX38409@kib.kiev.ua> <20161001115439.GY38409@kib.kiev.ua> <68a8ed6d-e302-799c-3d2c-1d85c48d07bf@citrin.ru> <20161001211025.GD38409@kib.kiev.ua> <999638f9-3fee-82e3-d67f-cffef53b74e8@citrin.ru> <20161002191349.GH38409@kib.kiev.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.6.1 (2016-04-27) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Oct 2016 17:49:16 -0000 On Mon, Oct 03, 2016 at 01:14:15PM -0400, Anton Yuzhaninov wrote: > With this patch I can exec various binaries from 8k geli when I boot > from a USB stick, but can't boot with root on this geli. Boot process > stops after init exec. > > DDB bt for init: > https://imgur.com/a/FXuzw > ps in DDB shows init in running state (CPU2). I did several bug fixing and read passes over the patch, below is the current version, hopefully more robust. BTW, do you have INVARIANTS and perhaps WITNESS in your kernel config ? diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 2af5383..66e8a8f 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -118,14 +119,14 @@ static vop_listextattr_t ffs_listextattr; static vop_openextattr_t ffs_openextattr; static vop_setextattr_t ffs_setextattr; static vop_vptofh_t ffs_vptofh; - +static vop_getpages_t ffs_getpages; /* Global vfs data structures for ufs. */ struct vop_vector ffs_vnodeops1 = { .vop_default = &ufs_vnodeops, .vop_fsync = ffs_fsync, .vop_fdatasync = ffs_fdatasync, - .vop_getpages = vnode_pager_local_getpages, + .vop_getpages = ffs_getpages, .vop_getpages_async = vnode_pager_local_getpages_async, .vop_lock1 = ffs_lock, .vop_read = ffs_read, @@ -147,7 +148,7 @@ struct vop_vector ffs_vnodeops2 = { .vop_default = &ufs_vnodeops, .vop_fsync = ffs_fsync, .vop_fdatasync = ffs_fdatasync, - .vop_getpages = vnode_pager_local_getpages, + .vop_getpages = ffs_getpages, .vop_getpages_async = vnode_pager_local_getpages_async, .vop_lock1 = ffs_lock, .vop_read = ffs_read, @@ -1784,3 +1788,98 @@ vop_vptofh { ufhp->ufid_gen = ip->i_gen; return (0); } + +SYSCTL_DECL(_vfs_ffs); +static int use_buf_pager; +SYSCTL_INT(_vfs_ffs, OID_AUTO, use_buf_pager, CTLFLAG_RW, &use_buf_pager, 0, + "always use buffer pager instead of bmap"); + +static int +ffs_getpages(struct vop_getpages_args *ap) +{ + struct vnode *vp; + vm_page_t *mm, m; + vm_object_t object; + struct buf *bp; + struct ufsmount *um; + vm_pindex_t pi; + ufs_lbn_t lbn, lbnp; + long bsize; + int count, error, i; + bool redo; + + vp = ap->a_vp; + mm = ap->a_m; + count = ap->a_count; + + um = VFSTOUFS(ap->a_vp->v_mount); + if (!use_buf_pager && um->um_devvp->v_bufobj.bo_bsize <= PAGE_SIZE) + return (vnode_pager_generic_getpages(vp, mm, count, + ap->a_rbehind, ap->a_rahead, NULL, NULL)); + + object = vp->v_object; + if (IDX_TO_OFF(mm[count - 1]->pindex) >= object->un_pager.vnp.vnp_size) + return (VM_PAGER_BAD); + VM_OBJECT_WLOCK(object); +again: + for (i = 0; i < count; i++) { + m = mm[i]; + vm_page_xunbusy(m); + vm_page_sbusy(m); + } + VM_OBJECT_WUNLOCK(object); + + lbnp = -1; + for (i = 0; i < count; i++) { + m = mm[i]; + if (m->valid == VM_PAGE_BITS_ALL) + continue; + lbn = lblkno(um->um_fs, IDX_TO_OFF(m->pindex)); + if (lbn != lbnp) { + bsize = blksize(um->um_fs, VTOI(vp), lbn); + error = bread_gb(vp, lbn, bsize, NOCRED, GB_UNMAPPED, + &bp); + if (error != 0) + break; + if (LIST_EMPTY(&bp->b_dep)) { + bp->b_flags |= B_RELBUF; + brelse(bp); + } else { + /* XXX */ + bqrelse(bp); + } + lbnp = lbn; + } + } + + VM_OBJECT_WLOCK(object); + redo = false; + for (i = 0; i < count; i++) { + m = mm[i]; + if (error == 0) { + if (i == count - 1) + vm_page_zero_invalid(m, TRUE); + else + KASSERT(m->valid == VM_PAGE_BITS_ALL, + ("run %d %p invalid", i, m)); + } + vm_page_sunbusy(m); + while (vm_page_busied(m)) { + pi = m->pindex; + vm_page_lock(m); + VM_OBJECT_WUNLOCK(object); + vm_page_busy_sleep(m, "ffspgl"); + VM_OBJECT_WLOCK(object); + m = vm_page_lookup(object, pi); + if (mm[i] != m) + mm[i] = m; + } + vm_page_xbusy(m); + if (m->valid != VM_PAGE_BITS_ALL) + redo = true; + } + if (redo && error == 0) + goto again; + VM_OBJECT_WUNLOCK(object); + return (error != 0 ? VM_PAGER_ERROR : VM_PAGER_OK); +}