version 1.8.4.2, 2008/12/13 01:15:24 |
version 1.9, 2008/07/31 05:38:05 |
Line 47 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 47 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/file.h> |
#include <sys/file.h> |
#include <sys/kauth.h> |
#include <sys/kauth.h> |
#include <sys/fstrans.h> |
#include <sys/fstrans.h> |
#include <sys/buf.h> |
|
|
|
#include <miscfs/genfs/genfs.h> |
#include <miscfs/genfs/genfs.h> |
#include <miscfs/genfs/genfs_node.h> |
#include <miscfs/genfs/genfs_node.h> |
Line 64 static int genfs_do_io(struct vnode *, o |
|
Line 63 static int genfs_do_io(struct vnode *, o |
|
void (*)(struct buf *)); |
void (*)(struct buf *)); |
static inline void genfs_rel_pages(struct vm_page **, int); |
static inline void genfs_rel_pages(struct vm_page **, int); |
|
|
|
#define MAX_READ_PAGES 16 /* XXXUBC 16 */ |
|
|
int genfs_maxdio = MAXPHYS; |
int genfs_maxdio = MAXPHYS; |
|
|
static inline void |
static inline void |
Line 110 genfs_getpages(void *v) |
|
Line 111 genfs_getpages(void *v) |
|
daddr_t lbn, blkno; |
daddr_t lbn, blkno; |
int i, error, npages, orignpages, npgs, run, ridx, pidx, pcount; |
int i, error, npages, orignpages, npgs, run, ridx, pidx, pcount; |
int fs_bshift, fs_bsize, dev_bshift; |
int fs_bshift, fs_bsize, dev_bshift; |
const int flags = ap->a_flags; |
int flags = ap->a_flags; |
size_t bytes, iobytes, tailstart, tailbytes, totalbytes, skipbytes; |
size_t bytes, iobytes, tailstart, tailbytes, totalbytes, skipbytes; |
vaddr_t kva; |
vaddr_t kva; |
struct buf *bp, *mbp; |
struct buf *bp, *mbp; |
Line 118 genfs_getpages(void *v) |
|
Line 119 genfs_getpages(void *v) |
|
struct vnode *devvp; |
struct vnode *devvp; |
struct genfs_node *gp = VTOG(vp); |
struct genfs_node *gp = VTOG(vp); |
struct uvm_object *uobj = &vp->v_uobj; |
struct uvm_object *uobj = &vp->v_uobj; |
struct vm_page *pg, **pgs, *pgs_onstack[UBC_MAX_PAGES]; |
struct vm_page *pg, **pgs, *pgs_onstack[MAX_READ_PAGES]; |
int pgs_size; |
int pgs_size; |
kauth_cred_t cred = curlwp->l_cred; /* XXXUBC curlwp */ |
kauth_cred_t cred = curlwp->l_cred; /* XXXUBC curlwp */ |
const bool async = (flags & PGO_SYNCIO) == 0; |
bool async = (flags & PGO_SYNCIO) == 0; |
const bool write = (ap->a_access_type & VM_PROT_WRITE) != 0; |
bool write = (ap->a_access_type & VM_PROT_WRITE) != 0; |
bool sawhole = false; |
bool sawhole = false; |
bool has_trans = false; |
bool has_trans = false; |
const bool overwrite = (flags & PGO_OVERWRITE) != 0; |
bool overwrite = (flags & PGO_OVERWRITE) != 0; |
const bool blockalloc = write && (flags & PGO_NOBLOCKALLOC) == 0; |
bool blockalloc = write && (flags & PGO_NOBLOCKALLOC) == 0; |
voff_t origvsize; |
voff_t origvsize; |
UVMHIST_FUNC("genfs_getpages"); UVMHIST_CALLED(ubchist); |
UVMHIST_FUNC("genfs_getpages"); UVMHIST_CALLED(ubchist); |
|
|
Line 136 genfs_getpages(void *v) |
|
Line 137 genfs_getpages(void *v) |
|
KASSERT(vp->v_type == VREG || vp->v_type == VDIR || |
KASSERT(vp->v_type == VREG || vp->v_type == VDIR || |
vp->v_type == VLNK || vp->v_type == VBLK); |
vp->v_type == VLNK || vp->v_type == VBLK); |
|
|
pgs = NULL; |
/* XXXUBC temp limit */ |
pgs_size = 0; |
if (*ap->a_count > MAX_READ_PAGES) { |
|
panic("genfs_getpages: too many pages"); |
|
} |
|
|
|
pgs = pgs_onstack; |
|
pgs_size = sizeof(pgs_onstack); |
|
|
startover: |
startover: |
error = 0; |
error = 0; |
|
|
goto out_err; |
goto out_err; |
} |
} |
} else { |
} else { |
pgs = pgs_onstack; |
/* pgs == pgs_onstack */ |
(void)memset(pgs, 0, pgs_size); |
memset(pgs, 0, pgs_size); |
} |
} |
|
|
|
|
UVMHIST_LOG(ubchist, "ridx %d npages %d startoff %ld endoff %ld", |
UVMHIST_LOG(ubchist, "ridx %d npages %d startoff %ld endoff %ld", |
ridx, npages, startoffset, endoffset); |
ridx, npages, startoffset, endoffset); |
|
|
|
|
* XXX: This assumes that we come here only via |
* XXX: This assumes that we come here only via |
* the mmio path |
* the mmio path |
*/ |
*/ |
if (vp->v_mount->mnt_wapbl) { |
if (vp->v_mount->mnt_wapbl && write) { |
error = WAPBL_BEGIN(vp->v_mount); |
error = WAPBL_BEGIN(vp->v_mount); |
} |
} |
|
|
if (!error) { |
if (!error) { |
error = GOP_ALLOC(vp, startoffset, |
error = GOP_ALLOC(vp, startoffset, |
npages << PAGE_SHIFT, 0, cred); |
npages << PAGE_SHIFT, 0, cred); |
if (vp->v_mount->mnt_wapbl) { |
if (vp->v_mount->mnt_wapbl && write) { |
WAPBL_END(vp->v_mount); |
WAPBL_END(vp->v_mount); |
} |
} |
} |
} |
|
|
} |
} |
|
|
out_err: |
out_err: |
if (pgs != NULL && pgs != pgs_onstack) |
if (pgs != pgs_onstack) |
kmem_free(pgs, pgs_size); |
kmem_free(pgs, pgs_size); |
if (has_trans) |
if (has_trans) |
fstrans_done(vp->v_mount); |
fstrans_done(vp->v_mount); |
Line 775 genfs_do_putpages(struct vnode *vp, off_ |
|
Line 779 genfs_do_putpages(struct vnode *vp, off_ |
|
int flags; |
int flags; |
int dirtygen; |
int dirtygen; |
bool modified; |
bool modified; |
bool need_wapbl; |
|
bool has_trans; |
bool has_trans; |
bool cleanall; |
bool cleanall; |
bool onworklst; |
bool onworklst; |
Line 790 genfs_do_putpages(struct vnode *vp, off_ |
|
Line 793 genfs_do_putpages(struct vnode *vp, off_ |
|
vp, uobj->uo_npages, startoff, endoff - startoff); |
vp, uobj->uo_npages, startoff, endoff - startoff); |
|
|
has_trans = false; |
has_trans = false; |
need_wapbl = (!pagedaemon && vp->v_mount && vp->v_mount->mnt_wapbl && |
|
(origflags & PGO_JOURNALLOCKED) == 0); |
|
|
|
retry: |
retry: |
modified = false; |
modified = false; |
|
|
if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL) |
if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL) |
vn_syncer_remove_from_worklist(vp); |
vn_syncer_remove_from_worklist(vp); |
} |
} |
if (has_trans) { |
if (has_trans) |
if (need_wapbl) |
|
WAPBL_END(vp->v_mount); |
|
fstrans_done(vp->v_mount); |
fstrans_done(vp->v_mount); |
} |
|
mutex_exit(slock); |
mutex_exit(slock); |
return (0); |
return (0); |
} |
} |
|
|
return error; |
return error; |
} else |
} else |
fstrans_start(vp->v_mount, FSTRANS_LAZY); |
fstrans_start(vp->v_mount, FSTRANS_LAZY); |
if (need_wapbl) { |
|
error = WAPBL_BEGIN(vp->v_mount); |
|
if (error) { |
|
fstrans_done(vp->v_mount); |
|
return error; |
|
} |
|
} |
|
has_trans = true; |
has_trans = true; |
mutex_enter(slock); |
mutex_enter(slock); |
goto retry; |
goto retry; |
|
|
goto retry; |
goto retry; |
} |
} |
|
|
if (has_trans) { |
if (has_trans) |
if (need_wapbl) |
|
WAPBL_END(vp->v_mount); |
|
fstrans_done(vp->v_mount); |
fstrans_done(vp->v_mount); |
} |
|
|
|
return (error); |
return (error); |
} |
} |
Line 1560 genfs_directio(struct vnode *vp, struct |
|
Line 1548 genfs_directio(struct vnode *vp, struct |
|
size_t len; |
size_t len; |
const int mask = DEV_BSIZE - 1; |
const int mask = DEV_BSIZE - 1; |
int error; |
int error; |
bool need_wapbl = (vp->v_mount && vp->v_mount->mnt_wapbl && |
|
(ioflag & IO_JOURNALLOCKED) == 0); |
|
|
|
/* |
/* |
* We only support direct I/O to user space for now. |
* We only support direct I/O to user space for now. |
Line 1583 genfs_directio(struct vnode *vp, struct |
|
Line 1569 genfs_directio(struct vnode *vp, struct |
|
return; |
return; |
} |
} |
|
|
if (need_wapbl) { |
|
error = WAPBL_BEGIN(vp->v_mount); |
|
if (error) |
|
return; |
|
} |
|
|
|
/* |
/* |
* Do as much of the uio as possible with direct I/O. |
* Do as much of the uio as possible with direct I/O. |
*/ |
*/ |
Line 1611 genfs_directio(struct vnode *vp, struct |
|
Line 1591 genfs_directio(struct vnode *vp, struct |
|
*/ |
*/ |
|
|
if (len == 0 || uio->uio_offset + len > vp->v_size) { |
if (len == 0 || uio->uio_offset + len > vp->v_size) { |
break; |
return; |
} |
} |
|
|
/* |
/* |
Line 1622 genfs_directio(struct vnode *vp, struct |
|
Line 1602 genfs_directio(struct vnode *vp, struct |
|
*/ |
*/ |
|
|
if (uio->uio_offset & mask || va & mask) { |
if (uio->uio_offset & mask || va & mask) { |
break; |
return; |
} |
} |
error = genfs_do_directio(vs, va, len, vp, uio->uio_offset, |
error = genfs_do_directio(vs, va, len, vp, uio->uio_offset, |
uio->uio_rw); |
uio->uio_rw); |
Line 1634 genfs_directio(struct vnode *vp, struct |
|
Line 1614 genfs_directio(struct vnode *vp, struct |
|
uio->uio_offset += len; |
uio->uio_offset += len; |
uio->uio_resid -= len; |
uio->uio_resid -= len; |
} |
} |
|
|
if (need_wapbl) |
|
WAPBL_END(vp->v_mount); |
|
} |
} |
|
|
/* |
/* |
Line 1673 genfs_do_directio(struct vmspace *vs, va |
|
Line 1650 genfs_do_directio(struct vmspace *vs, va |
|
paddr_t pa; |
paddr_t pa; |
vm_prot_t prot; |
vm_prot_t prot; |
int error, rv, poff, koff; |
int error, rv, poff, koff; |
const int pgoflags = PGO_CLEANIT | PGO_SYNCIO | PGO_JOURNALLOCKED | |
const int pgoflags = PGO_CLEANIT | PGO_SYNCIO | |
(rw == UIO_WRITE ? PGO_FREE : 0); |
(rw == UIO_WRITE ? PGO_FREE : 0); |
|
|
/* |
/* |