Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Sep 2014 12:28:29 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271619 - in head/sys: fs/ext2fs ufs/ffs vm
Message-ID:  <201409151228.s8FCSTKg062879@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Sep 15 12:28:29 2014
New Revision: 271619
URL: http://svnweb.freebsd.org/changeset/base/271619

Log:
  Provide the unique implementation for the VOP_GETPAGES() method used
  by ffs and ext2fs.  Remove duplicated call to vm_page_zero_invalid(),
  done by VOP and by vm_pager_getpages().  Use vm_pager_free_nonreq().
  
  Reviewed by:	alc (previous version)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	6 weeks (after r271596)

Modified:
  head/sys/fs/ext2fs/ext2_vnops.c
  head/sys/ufs/ffs/ffs_vnops.c
  head/sys/vm/vnode_pager.c
  head/sys/vm/vnode_pager.h

Modified: head/sys/fs/ext2fs/ext2_vnops.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c	Mon Sep 15 11:35:14 2014	(r271618)
+++ head/sys/fs/ext2fs/ext2_vnops.c	Mon Sep 15 12:28:29 2014	(r271619)
@@ -97,7 +97,6 @@ static int ext2_chown(struct vnode *, ui
 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;
@@ -128,7 +127,7 @@ struct vop_vector ext2_vnodeops = {
 	.vop_close =		ext2_close,
 	.vop_create =		ext2_create,
 	.vop_fsync =		ext2_fsync,
-	.vop_getpages =		ext2_getpages,
+	.vop_getpages =		vnode_pager_local_getpages,
 	.vop_getattr =		ext2_getattr,
 	.vop_inactive =		ext2_inactive,
 	.vop_ioctl =		ext2_ioctl,
@@ -2063,48 +2062,3 @@ 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;
-
-	mreq = ap->a_m[ap->a_reqpage];
-
-	/*
-	 * Since the caller has busied the requested page, that page's valid
-	 * field will not be changed by other threads.
-	 */
-	vm_page_assert_xbusied(mreq);
-
-	/*
-	 * 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.
-	 */
-	if (mreq->valid) {
-		VM_OBJECT_WLOCK(mreq->object);
-		if (mreq->valid != VM_PAGE_BITS_ALL)
-			vm_page_zero_invalid(mreq, TRUE);
-		pcount = round_page(ap->a_count) / PAGE_SIZE;
-		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;
-	}
-
-	return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
-					    ap->a_count,
-					    ap->a_reqpage);
-}

Modified: head/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vnops.c	Mon Sep 15 11:35:14 2014	(r271618)
+++ head/sys/ufs/ffs/ffs_vnops.c	Mon Sep 15 12:28:29 2014	(r271619)
@@ -104,7 +104,6 @@ extern int	ffs_rawread(struct vnode *vp,
 #endif
 static vop_fsync_t	ffs_fsync;
 static vop_lock1_t	ffs_lock;
-static vop_getpages_t	ffs_getpages;
 static vop_read_t	ffs_read;
 static vop_write_t	ffs_write;
 static int	ffs_extread(struct vnode *vp, struct uio *uio, int ioflag);
@@ -124,7 +123,7 @@ static vop_vptofh_t	ffs_vptofh;
 struct vop_vector ffs_vnodeops1 = {
 	.vop_default =		&ufs_vnodeops,
 	.vop_fsync =		ffs_fsync,
-	.vop_getpages =		ffs_getpages,
+	.vop_getpages =		vnode_pager_local_getpages,
 	.vop_lock1 =		ffs_lock,
 	.vop_read =		ffs_read,
 	.vop_reallocblks =	ffs_reallocblks,
@@ -143,7 +142,7 @@ struct vop_vector ffs_fifoops1 = {
 struct vop_vector ffs_vnodeops2 = {
 	.vop_default =		&ufs_vnodeops,
 	.vop_fsync =		ffs_fsync,
-	.vop_getpages =		ffs_getpages,
+	.vop_getpages =		vnode_pager_local_getpages,
 	.vop_lock1 =		ffs_lock,
 	.vop_read =		ffs_read,
 	.vop_reallocblks =	ffs_reallocblks,
@@ -847,53 +846,6 @@ ffs_write(ap)
 }
 
 /*
- * get page routine
- */
-static int
-ffs_getpages(ap)
-	struct vop_getpages_args *ap;
-{
-	int i;
-	vm_page_t mreq;
-	int pcount;
-
-	mreq = ap->a_m[ap->a_reqpage];
-
-	/*
-	 * Since the caller has busied the requested page, that page's valid
-	 * field will not be changed by other threads.
-	 */
-	vm_page_assert_xbusied(mreq);
-
-	/*
-	 * 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.
-	 */
-	if (mreq->valid) {
-		VM_OBJECT_WLOCK(mreq->object);
-		if (mreq->valid != VM_PAGE_BITS_ALL)
-			vm_page_zero_invalid(mreq, TRUE);
-		pcount = round_page(ap->a_count) / PAGE_SIZE;
-		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;
-	}
-
-	return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
-					    ap->a_count,
-					    ap->a_reqpage);
-}
-
-
-/*
  * Extended attribute area reading.
  */
 static int

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Mon Sep 15 11:35:14 2014	(r271618)
+++ head/sys/vm/vnode_pager.c	Mon Sep 15 12:28:29 2014	(r271619)
@@ -665,6 +665,39 @@ vnode_pager_getpages(vm_object_t object,
 }
 
 /*
+ * The implementation of VOP_GETPAGES() for local filesystems, where
+ * partially valid pages can only occur at the end of file.
+ */
+int
+vnode_pager_local_getpages(struct vop_getpages_args *ap)
+{
+	vm_page_t mreq;
+
+	mreq = ap->a_m[ap->a_reqpage];
+
+	/*
+	 * Since the caller has busied the requested page, that page's valid
+	 * field will not be changed by other threads.
+	 */
+	vm_page_assert_xbusied(mreq);
+
+	/*
+	 * The requested page has valid blocks.  Invalid part can only
+	 * exist at the end of file, and the page is made fully valid
+	 * by zeroing in vm_pager_getpages().  Free non-requested
+	 * pages, since no i/o is done to read its content.
+	 */
+	if (mreq->valid != 0) {
+		vm_pager_free_nonreq(mreq->object, ap->a_m, ap->a_reqpage,
+		    round_page(ap->a_count) / PAGE_SIZE);
+		return (VM_PAGER_OK);
+	}
+
+	return (vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
+	    ap->a_count, ap->a_reqpage));
+}
+
+/*
  * This is now called from local media FS's to operate against their
  * own vnodes if they fail to implement VOP_GETPAGES.
  */

Modified: head/sys/vm/vnode_pager.h
==============================================================================
--- head/sys/vm/vnode_pager.h	Mon Sep 15 11:35:14 2014	(r271618)
+++ head/sys/vm/vnode_pager.h	Mon Sep 15 12:28:29 2014	(r271619)
@@ -45,6 +45,8 @@ int vnode_pager_generic_getpages(struct 
 int vnode_pager_generic_putpages(struct vnode *vp, vm_page_t *m,
 					  int count, boolean_t sync,
 					  int *rtvals);
+struct vop_getpages_args;
+int vnode_pager_local_getpages(struct vop_getpages_args *ap);
 
 void vnode_pager_release_writecount(vm_object_t object, vm_offset_t start,
     vm_offset_t end);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409151228.s8FCSTKg062879>