summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2014-10-04 17:46:04 +0000
committerpfg <pfg@FreeBSD.org>2014-10-04 17:46:04 +0000
commit5c298394b4f57ee54e424e5a5aab39c6b5932437 (patch)
tree577ba8ae84539151856ac393f9eee660d4eaf305 /sys/fs
parent108145fb7318452119aa5fd3566a29fe991872bd (diff)
downloadFreeBSD-src-5c298394b4f57ee54e424e5a5aab39c6b5932437.zip
FreeBSD-src-5c298394b4f57ee54e424e5a5aab39c6b5932437.tar.gz
MFC r271467, r271468:
ext2fs: add ext2_getpages(). Literally copy/pasted from ffs_getpages(). Tested with: fsx
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/ext2fs/ext2_vnops.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index 2046e33..e68bc64 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -54,6 +54,7 @@
#include <sys/buf.h>
#include <sys/endian.h>
#include <sys/priv.h>
+#include <sys/rwlock.h>
#include <sys/mount.h>
#include <sys/unistd.h>
#include <sys/time.h>
@@ -65,9 +66,11 @@
#include <sys/file.h>
#include <vm/vm.h>
-#include <vm/vm_page.h>
-#include <vm/vm_object.h>
+#include <vm/vm_param.h>
#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
#include "opt_directio.h"
@@ -94,6 +97,7 @@ static int ext2_chown(struct vnode *, uid_t, gid_t, struct ucred *,
static vop_close_t ext2_close;
static vop_create_t ext2_create;
static vop_fsync_t ext2_fsync;
+static vop_getpages_t ext2_getpages;
static vop_getattr_t ext2_getattr;
static vop_ioctl_t ext2_ioctl;
static vop_link_t ext2_link;
@@ -124,6 +128,7 @@ struct vop_vector ext2_vnodeops = {
.vop_close = ext2_close,
.vop_create = ext2_create,
.vop_fsync = ext2_fsync,
+ .vop_getpages = ext2_getpages,
.vop_getattr = ext2_getattr,
.vop_inactive = ext2_inactive,
.vop_ioctl = ext2_ioctl,
@@ -2058,3 +2063,43 @@ ext2_write(struct vop_write_args *ap)
}
return (error);
}
+
+/*
+ * get page routine
+ */
+static int
+ext2_getpages(struct vop_getpages_args *ap)
+{
+ int i;
+ vm_page_t mreq;
+ int pcount;
+
+ pcount = round_page(ap->a_count) / PAGE_SIZE;
+ mreq = ap->a_m[ap->a_reqpage];
+
+ /*
+ * if ANY DEV_BSIZE blocks are valid on a large filesystem block,
+ * then the entire page is valid. Since the page may be mapped,
+ * user programs might reference data beyond the actual end of file
+ * occuring within the page. We have to zero that data.
+ */
+ VM_OBJECT_WLOCK(mreq->object);
+ if (mreq->valid) {
+ if (mreq->valid != VM_PAGE_BITS_ALL)
+ vm_page_zero_invalid(mreq, TRUE);
+ for (i = 0; i < pcount; i++) {
+ if (i != ap->a_reqpage) {
+ vm_page_lock(ap->a_m[i]);
+ vm_page_free(ap->a_m[i]);
+ vm_page_unlock(ap->a_m[i]);
+ }
+ }
+ VM_OBJECT_WUNLOCK(mreq->object);
+ return VM_PAGER_OK;
+ }
+ VM_OBJECT_WUNLOCK(mreq->object);
+
+ return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
+ ap->a_count,
+ ap->a_reqpage);
+}
OpenPOWER on IntegriCloud