summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_default.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_default.c')
-rw-r--r--sys/kern/vfs_default.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index b89d990..e9f8151 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -96,6 +96,7 @@ struct vop_vector default_vnodeops = {
.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 +985,58 @@ vop_stdallocate(struct vop_allocate_args *ap)
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 POSIX_FADV_WILLNEED:
+ /*
+ * Do nothing for now. Filesystems should provide a
+ * custom method which starts an asynchronous read of
+ * the requested region.
+ */
+ error = 0;
+ break;
+ case POSIX_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);
+ VFS_UNLOCK_GIANT(vfslocked);
+ break;
+ }
+ vinvalbuf(vp, V_CLEANONLY, 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_cache(vp->v_object, OFF_TO_IDX(start),
+ OFF_TO_IDX(end));
+ 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.
OpenPOWER on IntegriCloud