diff options
| author | chs <chs@NetBSD.org> | 2018-05-28 21:04:37 +0000 |
|---|---|---|
| committer | chs <chs@NetBSD.org> | 2018-05-28 21:04:37 +0000 |
| commit | 0dc745ed85bddbb15251e4a64e4cb0610e9dc8fc (patch) | |
| tree | f0d5fa671d7e2af2b8c75e1c6c76cb8b41aa46c3 /sys/miscfs | |
| parent | c7f1ea8ad8384829634787cdbf36f17f280ea8fd (diff) | |
add a genfs method to allow a file system to limit the range of pages
that are given to a single GOP_WRITE() call. needed by ZFS.
Diffstat (limited to 'sys/miscfs')
| -rw-r--r-- | sys/miscfs/genfs/genfs_io.c | 40 | ||||
| -rw-r--r-- | sys/miscfs/genfs/genfs_node.h | 6 |
2 files changed, 42 insertions, 4 deletions
diff --git a/sys/miscfs/genfs/genfs_io.c b/sys/miscfs/genfs/genfs_io.c index 62b531c5a8e..6fbe1b92103 100644 --- a/sys/miscfs/genfs/genfs_io.c +++ b/sys/miscfs/genfs/genfs_io.c @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_io.c,v 1.71 2017/10/28 00:37:13 pgoyette Exp $ */ +/* $NetBSD: genfs_io.c,v 1.72 2018/05/28 21:04:38 chs Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.71 2017/10/28 00:37:13 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.72 2018/05/28 21:04:38 chs Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1120,10 +1120,29 @@ retry: UVM_PAGE_OWN(pg, "genfs_putpages"); /* + * let the fs constrain the offset range of the cluster. + * we additionally constrain the range here such that + * it fits in the "pgs" pages array. + */ + + off_t fslo, fshi, genlo, lo; + GOP_PUTRANGE(vp, off, &fslo, &fshi); + KASSERT(fslo == trunc_page(fslo)); + KASSERT(fslo <= off); + KASSERT(fshi == trunc_page(fshi)); + KASSERT(fshi == 0 || off < fshi); + + if (off > MAXPHYS / 2) + genlo = trunc_page(off - (MAXPHYS / 2)); + else + genlo = 0; + lo = MAX(fslo, genlo); + + /* * first look backward. */ - npages = MIN(MAXPAGES >> 1, off >> PAGE_SHIFT); + npages = (off - lo) >> PAGE_SHIFT; nback = npages; uvn_findpages(uobj, off - PAGE_SIZE, &nback, &pgs[0], UFP_NOWAIT|UFP_NOALLOC|UFP_DIRTYONLY|UFP_BACKWARD); @@ -1150,6 +1169,9 @@ retry: */ npages = MAXPAGES - nback - 1; + if (fshi) + npages = MIN(npages, + (fshi - off - 1) >> PAGE_SHIFT); uvn_findpages(uobj, off + PAGE_SIZE, &npages, &pgs[nback + 1], UFP_NOWAIT|UFP_NOALLOC|UFP_DIRTYONLY); @@ -1314,6 +1336,18 @@ skip_scan: return (error); } +/* + * Default putrange method for file systems that do not care + * how many pages are given to one GOP_WRITE() call. + */ +void +genfs_gop_putrange(struct vnode *vp, off_t off, off_t *lop, off_t *hip) +{ + + *lop = 0; + *hip = 0; +} + int genfs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags) { diff --git a/sys/miscfs/genfs/genfs_node.h b/sys/miscfs/genfs/genfs_node.h index a804dc38029..7d237a8b8db 100644 --- a/sys/miscfs/genfs/genfs_node.h +++ b/sys/miscfs/genfs/genfs_node.h @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_node.h,v 1.21 2013/06/06 02:00:59 dholland Exp $ */ +/* $NetBSD: genfs_node.h,v 1.22 2018/05/28 21:04:38 chs Exp $ */ /* * Copyright (c) 2001 Chuck Silvers. @@ -46,6 +46,7 @@ struct genfs_ops { struct kauth_cred *); int (*gop_write)(struct vnode *, struct vm_page **, int, int); void (*gop_markupdate)(struct vnode *, int); + void (*gop_putrange)(struct vnode *, off_t, off_t *, off_t *); }; #define GOP_SIZE(vp, size, eobp, flags) \ @@ -54,6 +55,8 @@ struct genfs_ops { (*VTOG(vp)->g_op->gop_alloc)((vp), (off), (len), (flags), (cred)) #define GOP_WRITE(vp, pgs, npages, flags) \ (*VTOG(vp)->g_op->gop_write)((vp), (pgs), (npages), (flags)) +#define GOP_PUTRANGE(vp, off, lop, hip) \ + (*VTOG(vp)->g_op->gop_putrange)((vp), (off), (lop), (hip)) /* * GOP_MARKUPDATE: mark vnode's timestamps for update. @@ -85,6 +88,7 @@ struct genfs_node { void genfs_size(struct vnode *, off_t, off_t *, int); void genfs_node_init(struct vnode *, const struct genfs_ops *); void genfs_node_destroy(struct vnode *); +void genfs_gop_putrange(struct vnode *, off_t, off_t *, off_t *); int genfs_gop_write(struct vnode *, struct vm_page **, int, int); int genfs_gop_write_rwmap(struct vnode *, struct vm_page **, int, int); int genfs_compat_gop_write(struct vnode *, struct vm_page **, int, int); |
