Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Oct 2011 19:22:36 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 200537 for review
Message-ID:  <201110211922.p9LJMajE061942@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@200537?ac=10

Change 200537 by jhb@jhb_jhbbsd on 2011/10/21 19:22:32

	- Add a new VOP_ADVISE() to service "immediate" fadvise() requests
	  (FADV_*NEED).
	- Add a vop_stdadvise() based on the current fadvise()
	  implementation.

Affected files ...

.. //depot/projects/fadvise/sys/kern/vfs_default.c#2 edit
.. //depot/projects/fadvise/sys/kern/vfs_syscalls.c#8 edit
.. //depot/projects/fadvise/sys/kern/vnode_if.src#2 edit
.. //depot/projects/fadvise/sys/sys/vnode.h#2 edit

Differences ...

==== //depot/projects/fadvise/sys/kern/vfs_default.c#2 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <sys/lock.h>
 #include <sys/lockf.h>
 #include <sys/malloc.h>
+#include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/namei.h>
@@ -96,6 +97,7 @@
 
 	.vop_access =		vop_stdaccess,
 	.vop_accessx =		vop_stdaccessx,
+	.vop_advise =		vop_stdadvise,
 	.vop_advlock =		vop_stdadvlock,
 	.vop_advlockasync =	vop_stdadvlockasync,
 	.vop_advlockpurge =	vop_stdadvlockpurge,
@@ -984,6 +986,67 @@
 	return (error);
 }
 
+int
+vop_stdadvise(struct vop_advise_args *ap)
+{
+	struct vnode *vp;
+	off_t start, end;
+	int error, vfslocked;
+
+	vp = ap->a_vp;
+	switch (ap->a_advice) {
+	case FADV_WILLNEED:
+		/*
+		 * Apply the request to the backing VM object.
+		 *
+		 * XXX: madvise(MADV_WILLNEED) will not do readahead on
+		 * a file, perhaps FADV_WILLNEED should.
+		 */
+		start = trunc_page(ap->a_start);
+		end = round_page(ap->a_end);
+		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+		vn_lock(vp, LK_SHARED | LK_RETRY);
+		if (vp->v_object != NULL)
+			vm_object_madvise(vp->v_object, OFF_TO_IDX(start),
+			    atop(end - start), MADV_WILLNEED);
+		VOP_UNLOCK(vp, 0);
+		VFS_UNLOCK_GIANT(vfslocked);
+		error = 0;
+		break;
+	case FADV_DONTNEED:
+		/*
+		 * Flush any open FS buffers and then remove pages
+		 * from the backing VM object.  Using vinvalbuf() here
+		 * is a bit heavy-handed as it flushes all buffers for
+		 * the given vnode, not just the buffers covering the
+		 * requested range.
+		 */
+		error = 0;
+		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+		if (vp->v_iflag & VI_DOOMED) {
+			VOP_UNLOCK(vp, 0);
+			break;
+		}
+		vinvalbuf(vp, V_NORMAL, 0, 0);
+		if (vp->v_object != NULL) {
+			start = trunc_page(ap->a_start);
+			end = round_page(ap->a_end);
+			VM_OBJECT_LOCK(vp->v_object);
+			vm_object_page_remove(vp->v_object, OFF_TO_IDX(start),
+			    OFF_TO_IDX(end), OBJPR_CLEANONLY | OBJPR_DEBUG);
+			VM_OBJECT_UNLOCK(vp->v_object);
+		}
+		VOP_UNLOCK(vp, 0);
+		VFS_UNLOCK_GIANT(vfslocked);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	return (error);
+}
+
 /*
  * vfs default ops
  * used to fill the vfs function table to get reasonable default return values.

==== //depot/projects/fadvise/sys/kern/vfs_syscalls.c#8 (text+ko) ====

@@ -61,7 +61,6 @@
 #include <sys/filio.h>
 #include <sys/limits.h>
 #include <sys/linker.h>
-#include <sys/mman.h>
 #include <sys/sdt.h>
 #include <sys/stat.h>
 #include <sys/sx.h>
@@ -4858,8 +4857,8 @@
 {
 	struct file *fp;
 	struct vnode *vp;
-	off_t start, end;
-	int error, vfslocked;
+	off_t end;
+	int error;
 
 	if (uap->offset < 0 || uap->len < 0 ||
 	    uap->offset > OFF_MAX - uap->len)
@@ -4942,42 +4941,8 @@
 		mtx_pool_unlock(mtxpool_sleep, fp);
 		break;
 	case FADV_WILLNEED:
-		/*
-		 * Apply the request to the backing VM object.
-		 *
-		 * XXX: madvise(MADV_WILLNEED) will not do readahead on
-		 * a file, perhaps FADV_WILLNEED should.
-		 */
-		start = trunc_page(uap->offset);
-		end = round_page(end);
-		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
-		vn_lock(vp, LK_SHARED | LK_RETRY);
-		if (vp->v_object != NULL)
-			vm_object_madvise(vp->v_object, OFF_TO_IDX(start),
-			    atop(end - start), MADV_WILLNEED);
-		VOP_UNLOCK(vp, 0);
-		VFS_UNLOCK_GIANT(vfslocked);
-		break;
 	case FADV_DONTNEED:
-		/*
-		 * Flush any open FS buffers and then remove pages
-		 * from the backing VM object.
-		 */
-		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-		if (vp->v_iflag & VI_DOOMED) {
-			VOP_UNLOCK(vp, 0);
-			break;
-		}
-		vinvalbuf(vp, V_NORMAL, 0, 0);
-		if (vp->v_object != NULL) {
-			start = trunc_page(uap->offset);
-			end = round_page(end);
-			VM_OBJECT_LOCK(vp->v_object);
-			vm_object_page_remove(vp->v_object, OFF_TO_IDX(start),
-			    OFF_TO_IDX(end), OBJPR_CLEANONLY | OBJPR_DEBUG);
-			VM_OBJECT_UNLOCK(vp->v_object);
-		}
-		VOP_UNLOCK(vp, 0);
+		error = VOP_ADVISE(vp, uap->offset, end, uap->advice);
 		break;
 	}
 out:

==== //depot/projects/fadvise/sys/kern/vnode_if.src#2 (text+ko) ====

@@ -628,3 +628,12 @@
 	INOUT off_t *offset;
 	INOUT off_t *len;
 };
+
+%% advise	vp	U U U
+
+vop_advise {
+	IN struct vnode *vp;
+	IN off_t start;
+	IN off_t end;
+	IN int advice;
+};

==== //depot/projects/fadvise/sys/sys/vnode.h#2 (text+ko) ====

@@ -685,6 +685,7 @@
 int	vop_nopoll(struct vop_poll_args *);
 int	vop_stdaccess(struct vop_access_args *ap);
 int	vop_stdaccessx(struct vop_accessx_args *ap);
+int	vop_stdadvise(struct vop_advise_args *ap);
 int	vop_stdadvlock(struct vop_advlock_args *ap);
 int	vop_stdadvlockasync(struct vop_advlockasync_args *ap);
 int	vop_stdadvlockpurge(struct vop_advlockpurge_args *ap);



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