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>