diff options
author | pfg <pfg@FreeBSD.org> | 2014-10-04 17:46:04 +0000 |
---|---|---|
committer | pfg <pfg@FreeBSD.org> | 2014-10-04 17:46:04 +0000 |
commit | 5c298394b4f57ee54e424e5a5aab39c6b5932437 (patch) | |
tree | 577ba8ae84539151856ac393f9eee660d4eaf305 | |
parent | 108145fb7318452119aa5fd3566a29fe991872bd (diff) | |
download | FreeBSD-src-5c298394b4f57ee54e424e5a5aab39c6b5932437.zip FreeBSD-src-5c298394b4f57ee54e424e5a5aab39c6b5932437.tar.gz |
MFC r271467, r271468:
ext2fs: add ext2_getpages().
Literally copy/pasted from ffs_getpages().
Tested with: fsx
-rw-r--r-- | sys/fs/ext2fs/ext2_vnops.c | 49 |
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); +} |