1139825Simp/*- 21541Srgrimes * Copyright (c) 1990 University of Utah. 31541Srgrimes * Copyright (c) 1991, 1993 41541Srgrimes * The Regents of the University of California. All rights reserved. 51541Srgrimes * 61541Srgrimes * This code is derived from software contributed to Berkeley by 71541Srgrimes * the Systems Programming Group of the University of Utah Computer 81541Srgrimes * Science Department. 91541Srgrimes * 101541Srgrimes * Redistribution and use in source and binary forms, with or without 111541Srgrimes * modification, are permitted provided that the following conditions 121541Srgrimes * are met: 131541Srgrimes * 1. Redistributions of source code must retain the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer. 151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161541Srgrimes * notice, this list of conditions and the following disclaimer in the 171541Srgrimes * documentation and/or other materials provided with the distribution. 181541Srgrimes * 4. Neither the name of the University nor the names of its contributors 191541Srgrimes * may be used to endorse or promote products derived from this software 201541Srgrimes * without specific prior written permission. 211541Srgrimes * 221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321541Srgrimes * SUCH DAMAGE. 331541Srgrimes * 341541Srgrimes * @(#)vm_pager.h 8.4 (Berkeley) 1/12/94 3550477Speter * $FreeBSD$ 361541Srgrimes */ 371541Srgrimes 381541Srgrimes/* 391541Srgrimes * Pager routine interface definition. 401541Srgrimes */ 411541Srgrimes 421541Srgrimes#ifndef _VM_PAGER_ 431541Srgrimes#define _VM_PAGER_ 441541Srgrimes 4533058Sbde#include <sys/queue.h> 4633058Sbde 4760938SjakeTAILQ_HEAD(pagerlst, vm_object); 481541Srgrimes 49137457Sphktypedef void pgo_init_t(void); 50194766Skibtypedef vm_object_t pgo_alloc_t(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t, 51194766Skib struct ucred *); 52137457Sphktypedef void pgo_dealloc_t(vm_object_t); 53137457Sphktypedef int pgo_getpages_t(vm_object_t, vm_page_t *, int, int); 54137457Sphktypedef void pgo_putpages_t(vm_object_t, vm_page_t *, int, int, int *); 55137457Sphktypedef boolean_t pgo_haspage_t(vm_object_t, vm_pindex_t, int *, int *); 56137457Sphktypedef void pgo_pageunswapped_t(vm_page_t); 57137457Sphk 585455Sdgstruct pagerops { 59137457Sphk pgo_init_t *pgo_init; /* Initialize pager. */ 60137457Sphk pgo_alloc_t *pgo_alloc; /* Allocate pager. */ 61137457Sphk pgo_dealloc_t *pgo_dealloc; /* Disassociate. */ 62137457Sphk pgo_getpages_t *pgo_getpages; /* Get (read) page. */ 63137457Sphk pgo_putpages_t *pgo_putpages; /* Put (write) page. */ 64137457Sphk pgo_haspage_t *pgo_haspage; /* Does pager have page? */ 65137457Sphk pgo_pageunswapped_t *pgo_pageunswapped; 661541Srgrimes}; 671541Srgrimes 68118384Sphkextern struct pagerops defaultpagerops; 69118384Sphkextern struct pagerops swappagerops; 70118384Sphkextern struct pagerops vnodepagerops; 71118384Sphkextern struct pagerops devicepagerops; 72118384Sphkextern struct pagerops physpagerops; 73195840Sjhbextern struct pagerops sgpagerops; 74236925Skibextern struct pagerops mgtdevicepagerops; 75118384Sphk 761541Srgrimes/* 771541Srgrimes * get/put return values 781541Srgrimes * OK operation was successful 791541Srgrimes * BAD specified data was out of the accepted range 801541Srgrimes * FAIL specified data was in range, but doesn't exist 811541Srgrimes * PEND operations was initiated but not completed 821541Srgrimes * ERROR error while accessing data that is in range and exists 831541Srgrimes * AGAIN temporary resource shortage prevented operation from happening 841541Srgrimes */ 851541Srgrimes#define VM_PAGER_OK 0 861541Srgrimes#define VM_PAGER_BAD 1 871541Srgrimes#define VM_PAGER_FAIL 2 881541Srgrimes#define VM_PAGER_PEND 3 891541Srgrimes#define VM_PAGER_ERROR 4 901541Srgrimes#define VM_PAGER_AGAIN 5 911541Srgrimes 92108358Sdillon#define VM_PAGER_PUT_SYNC 0x0001 93108358Sdillon#define VM_PAGER_PUT_INVAL 0x0002 94108358Sdillon#define VM_PAGER_CLUSTER_OK 0x0008 9534206Sdyson 9655206Speter#ifdef _KERNEL 9730354Sphk 989759Sbdeextern vm_map_t pager_map; 9942957Sdillonextern struct pagerops *pagertab[]; 10075474Salfredextern struct mtx pbuf_mtx; 1019759Sbde 102194766Skibvm_object_t vm_pager_allocate(objtype_t, void *, vm_ooffset_t, vm_prot_t, 103194766Skib vm_ooffset_t, struct ucred *); 10492727Salfredvoid vm_pager_bufferinit(void); 10592727Salfredvoid vm_pager_deallocate(vm_object_t); 10692727Salfredstatic __inline int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int); 10792727Salfredstatic __inline boolean_t vm_pager_has_page(vm_object_t, vm_pindex_t, int *, int *); 10892727Salfredvoid vm_pager_init(void); 10992727Salfredvm_object_t vm_pager_object_lookup(struct pagerlst *, void *); 11042957Sdillon 11146349Salc/* 11246349Salc * vm_page_get_pages: 11346349Salc * 11446349Salc * Retrieve pages from the VM system in order to map them into an object 11546349Salc * ( or into VM space somewhere ). If the pagein was successful, we 11646349Salc * must fully validate it. 11746349Salc */ 11842957Sdillonstatic __inline int 11942957Sdillonvm_pager_get_pages( 12042957Sdillon vm_object_t object, 12142957Sdillon vm_page_t *m, 12242957Sdillon int count, 12342957Sdillon int reqpage 12442957Sdillon) { 12546349Salc int r; 12646349Salc 127116710Salc VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); 12846349Salc r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage); 12946349Salc if (r == VM_PAGER_OK && m[reqpage]->valid != VM_PAGE_BITS_ALL) { 13046349Salc vm_page_zero_invalid(m[reqpage], TRUE); 13146349Salc } 13292029Seivind return (r); 13342957Sdillon} 13442957Sdillon 13543129Sdillonstatic __inline void 13642957Sdillonvm_pager_put_pages( 13742957Sdillon vm_object_t object, 13842957Sdillon vm_page_t *m, 13942957Sdillon int count, 14042957Sdillon int flags, 14142957Sdillon int *rtvals 14242957Sdillon) { 143121455Salc 144121455Salc VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); 14543129Sdillon (*pagertab[object->type]->pgo_putpages) 14643129Sdillon (object, m, count, flags, rtvals); 14742957Sdillon} 14842957Sdillon 14958708Sdillon/* 15058708Sdillon * vm_pager_haspage 15158708Sdillon * 15258708Sdillon * Check to see if an object's pager has the requested page. The 15358708Sdillon * object's pager will also set before and after to give the caller 15458708Sdillon * some idea of the number of pages before and after the requested 15558708Sdillon * page can be I/O'd efficiently. 15658708Sdillon * 157146355Salc * The object must be locked. 15858708Sdillon */ 15942957Sdillonstatic __inline boolean_t 16042957Sdillonvm_pager_has_page( 16142957Sdillon vm_object_t object, 16242957Sdillon vm_pindex_t offset, 16342957Sdillon int *before, 16442957Sdillon int *after 16542957Sdillon) { 16676827Salfred boolean_t ret; 16776827Salfred 168116695Salc VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); 16976827Salfred ret = (*pagertab[object->type]->pgo_haspage) 17076827Salfred (object, offset, before, after); 17176827Salfred return (ret); 17242957Sdillon} 17342957Sdillon 17442957Sdillon/* 17542957Sdillon * vm_pager_page_unswapped 17642957Sdillon * 177146355Salc * Destroy swap associated with the page. 17842957Sdillon * 179146355Salc * The object containing the page must be locked. 18042957Sdillon * This function may not block. 181118528Sphk * 182118528Sphk * XXX: A much better name would be "vm_pager_page_dirtied()" 183118528Sphk * XXX: It is not obvious if this could be profitably used by any 184118528Sphk * XXX: pagers besides the swap_pager or if it should even be a 185118528Sphk * XXX: generic pager_op in the first place. 18642957Sdillon */ 18742957Sdillonstatic __inline void 18842957Sdillonvm_pager_page_unswapped(vm_page_t m) 18942957Sdillon{ 190121455Salc 191121455Salc VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); 19242957Sdillon if (pagertab[m->object->type]->pgo_pageunswapped) 19342957Sdillon (*pagertab[m->object->type]->pgo_pageunswapped)(m); 19442957Sdillon} 19542957Sdillon 196229383Skibstruct cdev_pager_ops { 197229383Skib int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset, 198229383Skib int prot, vm_page_t *mres); 199229383Skib int (*cdev_pg_ctor)(void *handle, vm_ooffset_t size, vm_prot_t prot, 200229383Skib vm_ooffset_t foff, struct ucred *cred, u_short *color); 201229383Skib void (*cdev_pg_dtor)(void *handle); 202229383Skib}; 203229383Skib 204229383Skibvm_object_t cdev_pager_allocate(void *handle, enum obj_type tp, 205229383Skib struct cdev_pager_ops *ops, vm_ooffset_t size, vm_prot_t prot, 206229383Skib vm_ooffset_t foff, struct ucred *cred); 207229383Skibvm_object_t cdev_pager_lookup(void *handle); 208229383Skibvoid cdev_pager_free_page(vm_object_t object, vm_page_t m); 209229383Skib 21092029Seivind#endif /* _KERNEL */ 2115455Sdg#endif /* _VM_PAGER_ */ 212