PERFORCE change 200537 for review
John Baldwin
jhb at FreeBSD.org
Fri Oct 21 19:22:37 UTC 2011
http://p4web.freebsd.org/@@200537?ac=10
Change 200537 by jhb at 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);
More information about the p4-projects
mailing list