summaryrefslogtreecommitdiff
path: root/sys/miscfs
diff options
context:
space:
mode:
authorchs <chs@NetBSD.org>2018-05-28 21:04:37 +0000
committerchs <chs@NetBSD.org>2018-05-28 21:04:37 +0000
commit0dc745ed85bddbb15251e4a64e4cb0610e9dc8fc (patch)
treef0d5fa671d7e2af2b8c75e1c6c76cb8b41aa46c3 /sys/miscfs
parentc7f1ea8ad8384829634787cdbf36f17f280ea8fd (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.c40
-rw-r--r--sys/miscfs/genfs/genfs_node.h6
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);