Date: Sun, 2 Oct 2016 22:13:49 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Anton Yuzhaninov <citrin@citrin.ru> Cc: "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org> Subject: Re: UFS: unaligned read from GELI with 8k sectorsize Message-ID: <20161002191349.GH38409@kib.kiev.ua> In-Reply-To: <999638f9-3fee-82e3-d67f-cffef53b74e8@citrin.ru> References: <f84b069b-aeee-ff3c-d4f9-e2fe3caaddb1@citrin.ru> <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>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Oct 01, 2016 at 06:02:14PM -0400, Anton Yuzhaninov wrote: > DDB backtrace for shell: > https://imgur.com/a/JDLry I see. I was able to reproduce it with gnop -S 8k over swap-backed md. The following patch worked for me. diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 2af5383..c9cd4dc 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -118,14 +118,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 +147,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 +1787,95 @@ vop_vptofh { ufhp->ufid_gen = ip->i_gen; return (0); } + +static int +ffs_getpages(struct vop_getpages_args *ap) +{ + struct vnode *vp; + vm_page_t *mm, m, m1; + vm_object_t object; + struct bufobj *bo; + struct buf *bp; + struct fs *fs; + 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; + + bo = &VFSTOUFS(ap->a_vp->v_mount)->um_devvp->v_bufobj; + if (bo->bo_bsize <= PAGE_SIZE) + return (vnode_pager_generic_getpages(vp, mm, count, + ap->a_rbehind, ap->a_rahead, NULL, NULL)); + + object = vp->v_object; + VM_OBJECT_WLOCK(object); + if (IDX_TO_OFF(mm[count - 1]->pindex) >= object->un_pager.vnp.vnp_size) + return (VM_PAGER_BAD); +again: + for (i = 0; i < count; i++) { + vm_page_xunbusy(mm[i]); + vm_page_sbusy(mm[i]); + } + VM_OBJECT_WUNLOCK(object); + + fs = VFSTOUFS(vp->v_mount)->um_fs; + lbnp = -1; + for (i = 0; i < count; i++) { + lbn = lblkno(fs, OFF_TO_IDX(mm[i]->pindex)); + if (lbn != lbnp) { + bsize = blksize(fs, VTOI(vp), lbn); + error = bread_gb(vp, lbn, bsize, NOCRED, GB_UNMAPPED, + &bp); + if (error == 0) { + if (LIST_EMPTY(&bp->b_dep)) { + bp->b_flags |= B_RELBUF; + brelse(bp); + } else { + /* XXX */ + bqrelse(bp); + } + lbnp = lbn; + } else { + break; + } + } + } + + VM_OBJECT_WLOCK(object); + if (error == 0) + vm_page_zero_invalid(mm[count - 1], TRUE); + redo = false; + for (i = 0; i < count; i++) { + KASSERT(mm[i]->valid == VM_PAGE_BITS_ALL, + ("run %d %p invalid", i, mm[i])); + vm_page_sunbusy(mm[i]); +wait: + while (vm_page_busied(mm[i])) { + pi = mm[i]->pindex; + vm_page_lock(mm[i]); + VM_OBJECT_WUNLOCK(object); + vm_page_busy_sleep(mm[i], "ffspgl"); + VM_OBJECT_WLOCK(object); + m1 = vm_page_lookup(object, pi); + if (m1 != mm[i]) + mm[i] = m1; + if (vm_page_busied(m1)) { + m = m1; + goto wait; + } + vm_page_xbusy(m1); + if (m1->valid != VM_PAGE_BITS_ALL) + redo = true; + } + vm_page_xbusy(mm[i]); + } + if (redo && error == 0) + goto again; + VM_OBJECT_WUNLOCK(object); + return (error != 0 ? VM_PAGER_ERROR : VM_PAGER_OK); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20161002191349.GH38409>