summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-11-29 08:20:55 +0000
committerkib <kib@FreeBSD.org>2016-11-29 08:20:55 +0000
commitb646b68fbb596474a247384def9dad376176ada6 (patch)
tree498b089b0fb2910f4b137effa83e9f9b91b22138
parentfc5be6d0299c1ec11afb2bc30478b614ab25f964 (diff)
downloadFreeBSD-src-b646b68fbb596474a247384def9dad376176ada6.zip
FreeBSD-src-b646b68fbb596474a247384def9dad376176ada6.tar.gz
MFC r308980:
Use buffer pager for NFS. MFC note: really do not, by default.
-rw-r--r--sys/fs/nfsclient/nfs_clbio.c38
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c13
2 files changed, 48 insertions, 3 deletions
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index 45a48cf..2649d95 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -78,6 +78,40 @@ static int nfs_directio_write(struct vnode *vp, struct uio *uiop,
/*
* Vnode op for VM getpages.
*/
+SYSCTL_DECL(_vfs_nfs);
+static int use_buf_pager = 0;
+SYSCTL_INT(_vfs_nfs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN,
+ &use_buf_pager, 0,
+ "Use buffer pager instead of direct readrpc call");
+
+static daddr_t
+ncl_gbp_getblkno(struct vnode *vp, vm_ooffset_t off)
+{
+
+ return (off / vp->v_bufobj.bo_bsize);
+}
+
+static int
+ncl_gbp_getblksz(struct vnode *vp, daddr_t lbn)
+{
+ struct nfsnode *np;
+ u_quad_t nsize;
+ int biosize, bcount;
+
+ np = VTONFS(vp);
+ mtx_lock(&np->n_mtx);
+ nsize = np->n_size;
+ mtx_unlock(&np->n_mtx);
+
+ biosize = vp->v_bufobj.bo_bsize;
+ bcount = biosize;
+ if ((off_t)lbn * biosize >= nsize)
+ bcount = 0;
+ else if ((off_t)(lbn + 1) * biosize > nsize)
+ bcount = nsize - (off_t)lbn * biosize;
+ return (bcount);
+}
+
int
ncl_getpages(struct vop_getpages_args *ap)
{
@@ -126,6 +160,10 @@ ncl_getpages(struct vop_getpages_args *ap)
} else
mtx_unlock(&nmp->nm_mtx);
+ if (use_buf_pager)
+ return (vfs_bio_getpages(vp, pages, npages, ap->a_rbehind,
+ ap->a_rahead, ncl_gbp_getblkno, ncl_gbp_getblksz));
+
/*
* If the requested page is partially valid, just return it and
* allow the pager to zero-out the blanks. Partially valid pages
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 00adee1..11de5c2 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -2569,13 +2569,20 @@ ncl_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
static int
nfs_strategy(struct vop_strategy_args *ap)
{
- struct buf *bp = ap->a_bp;
+ struct buf *bp;
+ struct vnode *vp;
struct ucred *cr;
+ bp = ap->a_bp;
+ vp = ap->a_vp;
+ KASSERT(bp->b_vp == vp, ("missing b_getvp"));
KASSERT(!(bp->b_flags & B_DONE),
("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
BUF_ASSERT_HELD(bp);
+ if (vp->v_type == VREG && bp->b_blkno == bp->b_lblkno)
+ bp->b_blkno = bp->b_lblkno * (vp->v_bufobj.bo_bsize /
+ DEV_BSIZE);
if (bp->b_iocmd == BIO_READ)
cr = bp->b_rcred;
else
@@ -2587,8 +2594,8 @@ nfs_strategy(struct vop_strategy_args *ap)
* otherwise just do it ourselves.
*/
if ((bp->b_flags & B_ASYNC) == 0 ||
- ncl_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
- (void) ncl_doio(ap->a_vp, bp, cr, curthread, 1);
+ ncl_asyncio(VFSTONFS(vp->v_mount), bp, NOCRED, curthread))
+ (void) ncl_doio(vp, bp, cr, curthread, 1);
return (0);
}
OpenPOWER on IntegriCloud