#ifndef _VM_VM_PAGER_H_
#define _VM_VM_PAGER_H_
#ifndef _SYS_QUEUE_H_
#include <sys/queue.h>
#endif
#ifndef _VM_VM_PAGE_H_
#include <vm/vm_page.h>
#endif
#ifndef _VM_VM_OBJECT_H_
#include <vm/vm_object.h>
#endif
#ifdef _KERNEL
TAILQ_HEAD(pagerlst, vm_object);
struct buf;
struct bio;
typedef void pgo_dealloc_t(vm_object_t);
typedef int pgo_getpage_t(vm_object_t, vm_pindex_t, vm_page_t *, int);
typedef void pgo_putpages_t(vm_object_t, vm_page_t *, int, int, int *);
typedef boolean_t pgo_haspage_t(vm_object_t, vm_pindex_t);
struct pagerops {
pgo_dealloc_t *pgo_dealloc;
pgo_getpage_t *pgo_getpage;
pgo_putpages_t *pgo_putpages;
pgo_haspage_t *pgo_haspage;
};
#endif
#define VM_PAGER_OK 0
#define VM_PAGER_BAD 1
#define VM_PAGER_FAIL 2
#define VM_PAGER_PEND 3
#define VM_PAGER_ERROR 4
#define VM_PAGER_AGAIN 5
#ifdef _KERNEL
struct vnode;
extern struct vm_map *pager_map;
extern int pager_map_size;
extern struct pagerops *pagertab[];
vm_object_t default_pager_alloc(void *, off_t, vm_prot_t, off_t);
vm_object_t dev_pager_alloc(void *, off_t, vm_prot_t, off_t);
vm_object_t phys_pager_alloc(void *, off_t, vm_prot_t, off_t);
vm_object_t swap_pager_alloc(void *, off_t, vm_prot_t, off_t);
vm_object_t vnode_pager_alloc (void *, off_t, vm_prot_t, off_t, int, int);
vm_object_t vnode_pager_reference (struct vnode *);
void vm_pager_deallocate (vm_object_t);
static __inline int vm_pager_get_page (vm_object_t, vm_pindex_t,
vm_page_t *, int);
static __inline boolean_t vm_pager_has_page (vm_object_t, vm_pindex_t);
vm_object_t vm_pager_object_lookup(struct pagerlst *, void *);
void vm_pager_sync (void);
struct buf *getchainbuf(struct buf *bp, struct vnode *vp, int flags);
void flushchainbuf(struct buf *nbp);
void waitchainbuf(struct buf *bp, int count, int done);
void autochaindone(struct buf *bp);
void swap_pager_strategy(vm_object_t object, struct bio *bio);
void swap_pager_unswapped (vm_page_t m);
static __inline int
vm_pager_get_page(vm_object_t object, vm_pindex_t pindex,
vm_page_t *m, int seqaccess)
{
int r;
r = (*pagertab[object->type]->pgo_getpage)(object, pindex,
m, seqaccess);
if (r == VM_PAGER_OK && (*m)->valid != VM_PAGE_BITS_ALL) {
vm_page_zero_invalid(*m, TRUE);
}
return(r);
}
static __inline void
vm_pager_put_pages(
vm_object_t object,
vm_page_t *m,
int count,
int flags,
int *rtvals
) {
(*pagertab[object->type]->pgo_putpages)
(object, m, count, flags, rtvals);
}
static __inline boolean_t
vm_pager_has_page(vm_object_t object, vm_pindex_t offset)
{
return ((*pagertab[object->type]->pgo_haspage)(object, offset));
}
struct cdev_pager_ops {
int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset,
int prot, vm_page_t *mres);
int (*cdev_pg_ctor)(void *handle, vm_ooffset_t size, vm_prot_t prot,
vm_ooffset_t foff, struct ucred *cred, u_short *color);
void (*cdev_pg_dtor)(void *handle);
};
vm_object_t cdev_pager_allocate(void *handle, enum obj_type tp,
struct cdev_pager_ops *ops, vm_ooffset_t size, vm_prot_t prot,
vm_ooffset_t foff, struct ucred *cred);
vm_object_t cdev_pager_lookup(void *handle);
void cdev_pager_free_page(vm_object_t object, vm_page_t m);
#endif
#endif