Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/fuse/fuse_vnops.c
Show First 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | |||||
* XXX: This feature is highly experimental and can bring to instabilities, | * XXX: This feature is highly experimental and can bring to instabilities, | ||||
* needs revisiting before to be enabled by default. | * needs revisiting before to be enabled by default. | ||||
*/ | */ | ||||
static int fuse_reclaim_revoked = 0; | static int fuse_reclaim_revoked = 0; | ||||
SYSCTL_INT(_vfs_fuse, OID_AUTO, reclaim_revoked, CTLFLAG_RW, | SYSCTL_INT(_vfs_fuse, OID_AUTO, reclaim_revoked, CTLFLAG_RW, | ||||
&fuse_reclaim_revoked, 0, ""); | &fuse_reclaim_revoked, 0, ""); | ||||
int fuse_pbuf_freecnt = -1; | uma_zone_t fuse_pbuf_zone; | ||||
#define fuse_vm_page_lock(m) vm_page_lock((m)); | #define fuse_vm_page_lock(m) vm_page_lock((m)); | ||||
#define fuse_vm_page_unlock(m) vm_page_unlock((m)); | #define fuse_vm_page_unlock(m) vm_page_unlock((m)); | ||||
#define fuse_vm_page_lock_queues() ((void)0) | #define fuse_vm_page_lock_queues() ((void)0) | ||||
#define fuse_vm_page_unlock_queues() ((void)0) | #define fuse_vm_page_unlock_queues() ((void)0) | ||||
/* | /* | ||||
struct vnop_access_args { | struct vnop_access_args { | ||||
▲ Show 20 Lines • Show All 1,606 Lines • ▼ Show 20 Lines | fuse_vnop_getpages(struct vop_getpages_args *ap) | ||||
if (pages[npages - 1]->valid != 0 && --npages == 0) | if (pages[npages - 1]->valid != 0 && --npages == 0) | ||||
goto out; | goto out; | ||||
VM_OBJECT_WUNLOCK(vp->v_object); | VM_OBJECT_WUNLOCK(vp->v_object); | ||||
/* | /* | ||||
* We use only the kva address for the buffer, but this is extremely | * We use only the kva address for the buffer, but this is extremely | ||||
* convenient and fast. | * convenient and fast. | ||||
*/ | */ | ||||
bp = getpbuf(&fuse_pbuf_freecnt); | bp = uma_zalloc(fuse_pbuf_zone, M_WAITOK); | ||||
kva = (vm_offset_t)bp->b_data; | kva = (vm_offset_t)bp->b_data; | ||||
pmap_qenter(kva, pages, npages); | pmap_qenter(kva, pages, npages); | ||||
VM_CNT_INC(v_vnodein); | VM_CNT_INC(v_vnodein); | ||||
VM_CNT_ADD(v_vnodepgsin, npages); | VM_CNT_ADD(v_vnodepgsin, npages); | ||||
count = npages << PAGE_SHIFT; | count = npages << PAGE_SHIFT; | ||||
iov.iov_base = (caddr_t)kva; | iov.iov_base = (caddr_t)kva; | ||||
iov.iov_len = count; | iov.iov_len = count; | ||||
uio.uio_iov = &iov; | uio.uio_iov = &iov; | ||||
uio.uio_iovcnt = 1; | uio.uio_iovcnt = 1; | ||||
uio.uio_offset = IDX_TO_OFF(pages[0]->pindex); | uio.uio_offset = IDX_TO_OFF(pages[0]->pindex); | ||||
uio.uio_resid = count; | uio.uio_resid = count; | ||||
uio.uio_segflg = UIO_SYSSPACE; | uio.uio_segflg = UIO_SYSSPACE; | ||||
uio.uio_rw = UIO_READ; | uio.uio_rw = UIO_READ; | ||||
uio.uio_td = td; | uio.uio_td = td; | ||||
error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred); | error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred); | ||||
pmap_qremove(kva, npages); | pmap_qremove(kva, npages); | ||||
relpbuf(bp, &fuse_pbuf_freecnt); | uma_zfree(fuse_pbuf_zone, bp); | ||||
if (error && (uio.uio_resid == count)) { | if (error && (uio.uio_resid == count)) { | ||||
FS_DEBUG("error %d\n", error); | FS_DEBUG("error %d\n", error); | ||||
return VM_PAGER_ERROR; | return VM_PAGER_ERROR; | ||||
} | } | ||||
/* | /* | ||||
* Calculate the number of bytes read and validate only that number | * Calculate the number of bytes read and validate only that number | ||||
* of bytes. Note that due to pending writes, size may be 0. This | * of bytes. Note that due to pending writes, size may be 0. This | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | if (offset + count > fsize) { | ||||
count = fsize - offset; | count = fsize - offset; | ||||
if (count < 0) | if (count < 0) | ||||
count = 0; | count = 0; | ||||
} | } | ||||
/* | /* | ||||
* We use only the kva address for the buffer, but this is extremely | * We use only the kva address for the buffer, but this is extremely | ||||
* convenient and fast. | * convenient and fast. | ||||
*/ | */ | ||||
bp = getpbuf(&fuse_pbuf_freecnt); | bp = uma_zalloc(fuse_pbuf_zone, M_WAITOK); | ||||
kva = (vm_offset_t)bp->b_data; | kva = (vm_offset_t)bp->b_data; | ||||
pmap_qenter(kva, pages, npages); | pmap_qenter(kva, pages, npages); | ||||
VM_CNT_INC(v_vnodeout); | VM_CNT_INC(v_vnodeout); | ||||
VM_CNT_ADD(v_vnodepgsout, count); | VM_CNT_ADD(v_vnodepgsout, count); | ||||
iov.iov_base = (caddr_t)kva; | iov.iov_base = (caddr_t)kva; | ||||
iov.iov_len = count; | iov.iov_len = count; | ||||
uio.uio_iov = &iov; | uio.uio_iov = &iov; | ||||
uio.uio_iovcnt = 1; | uio.uio_iovcnt = 1; | ||||
uio.uio_offset = offset; | uio.uio_offset = offset; | ||||
uio.uio_resid = count; | uio.uio_resid = count; | ||||
uio.uio_segflg = UIO_SYSSPACE; | uio.uio_segflg = UIO_SYSSPACE; | ||||
uio.uio_rw = UIO_WRITE; | uio.uio_rw = UIO_WRITE; | ||||
uio.uio_td = td; | uio.uio_td = td; | ||||
error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred); | error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred); | ||||
pmap_qremove(kva, npages); | pmap_qremove(kva, npages); | ||||
relpbuf(bp, &fuse_pbuf_freecnt); | uma_zfree(fuse_pbuf_zone, bp); | ||||
if (!error) { | if (!error) { | ||||
int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; | int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; | ||||
for (i = 0; i < nwritten; i++) { | for (i = 0; i < nwritten; i++) { | ||||
rtvals[i] = VM_PAGER_OK; | rtvals[i] = VM_PAGER_OK; | ||||
VM_OBJECT_WLOCK(pages[i]->object); | VM_OBJECT_WLOCK(pages[i]->object); | ||||
vm_page_undirty(pages[i]); | vm_page_undirty(pages[i]); | ||||
▲ Show 20 Lines • Show All 402 Lines • Show Last 20 Lines |