PERFORCE change 195924 for review
Ilya Putsikau
ilya at FreeBSD.org
Sat Jul 9 08:57:20 UTC 2011
http://p4web.freebsd.org/@@195924?ac=10
Change 195924 by ilya at ilya_triton2011 on 2011/07/09 08:57:08
IO cleanup. Remove fuse_io_vnode, fuse_io_p2p, PAGEOP_TRANSLATE_UIO
Affected files ...
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#15 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#8 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#36 edit
Differences ...
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#15 (text+ko) ====
@@ -45,22 +45,14 @@
#include "fuse_debug.h"
static int fuse_read_directbackend(struct fuse_io_data *fioda);
-static int fuse_io_p2p(struct fuse_io_data *fioda, struct fuse_dispatcher *fdip);
static int fuse_read_biobackend(struct fuse_io_data *fioda);
static int fuse_write_directbackend(struct fuse_io_data *fioda);
static int fuse_write_biobackend(struct fuse_io_data *fioda);
static fuse_buffeater_t fuse_std_buffeater;
-/****************
- *
- * >>> Low level I/O routines and interface to them
- *
- ****************/
-
-/* main I/O dispatch routine */
int
-fuse_io_dispatch(struct vnode *vp, struct uio *uio, int flag,
+fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
struct ucred *cred)
{
struct fuse_filehandle *fufh;
@@ -91,7 +83,7 @@
* we hardwire it into the file's private data (similarly to Linux,
* btw.).
*/
- directio = (flag & O_DIRECT) || !fuse_vnode_cache_enable(vp);
+ directio = (ioflag & IO_DIRECT) || !fuse_vnode_cache_enable(vp);
switch (uio->uio_rw) {
case UIO_READ:
@@ -99,21 +91,21 @@
fioda.buffeater = fuse_std_buffeater;
if (directio) {
- DEBUG2G("direct read of vnode %ju via file handle %ju\n",
+ DEBUG("direct read of vnode %ju via file handle %ju\n",
(uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);
err = fuse_read_directbackend(&fioda);
} else {
- DEBUG2G("buffered read of vnode %ju\n", (uintmax_t)VTOILLU(vp));
+ DEBUG("buffered read of vnode %ju\n", (uintmax_t)VTOILLU(vp));
err = fuse_read_biobackend(&fioda);
}
break;
case UIO_WRITE:
if (directio) {
- DEBUG2G("direct write of vnode %ju via file handle %ju\n",
+ DEBUG("direct write of vnode %ju via file handle %ju\n",
(uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);
err = fuse_write_directbackend(&fioda);
} else {
- DEBUG2G("buffered write of vnode %ju\n", (uintmax_t)VTOILLU(vp));
+ DEBUG("buffered write of vnode %ju\n", (uintmax_t)VTOILLU(vp));
err = fuse_write_biobackend(&fioda);
}
break;
@@ -126,32 +118,7 @@
return (err);
}
-/* dispatch routine for vnode based I/O */
-int
-fuse_io_vnode(struct vnode *vp, struct uio *uio,
- int ioflag, struct ucred *cred)
-{
- int fflag = (uio->uio_rw == UIO_READ) ? FREAD : FWRITE;
- int err;
-
- if (ioflag & IO_DIRECT)
- fflag |= O_DIRECT;
- if (ioflag & IO_NDELAY)
- fflag |= FNONBLOCK;
- if (ioflag & IO_APPEND)
- fflag |= O_APPEND;
- if (ioflag & IO_ASYNC)
- fflag |= O_ASYNC;
- if (ioflag & IO_SYNC)
- fflag |= O_SYNC;
-
- err = fuse_io_dispatch(vp, uio, fflag, cred);
-
- DEBUG("return with %d\n", err);
- return (err);
-}
-
-int
+static int
fuse_read_biobackend(struct fuse_io_data *fioda)
{
@@ -279,13 +246,6 @@
* processing (we are not called from readdir) we can already invoke
* an optimized, "peer-to-peer" I/O routine.
*/
- if (buffe == fuse_std_buffeater && uio->uio_segflg == UIO_SYSSPACE) {
- if ((err = fuse_io_p2p(fioda, &fdi)))
- goto out;
- else
- goto done;
- }
-
while (uio->uio_resid > 0) {
fdi.iosize = sizeof(*fri);
fdisp_make_vp(&fdi, op, vp, td, cred);
@@ -307,97 +267,12 @@
break;
}
-done:
fuse_ticket_drop(fdi.tick);
out:
return ((err == -1) ? 0 : err);
}
-/* direct I/O routine with no intermediate buffer */
-static int
-fuse_io_p2p(struct fuse_io_data *fioda, struct fuse_dispatcher *fdip)
-{
- struct vnode *vp = fioda->vp;
- struct fuse_filehandle *fufh = fioda->fufh;
- struct uio *uio = fioda->uio;
- struct ucred *cred = fioda->cred;
- struct thread *td = fioda->td;
- enum fuse_opcode op;
-
- int err = 0;
- int chunksize = 0;
- struct iovec *iov;
- int nmax = (uio->uio_rw == UIO_READ) ?
- fuse_get_mpdata(vp->v_mount)->max_read :
- fuse_get_mpdata(vp->v_mount)->max_write;
-
- op = fioda->opcode ?:
- ((uio->uio_rw == UIO_READ) ? FUSE_READ : FUSE_WRITE);
-
- iov = uio->uio_iov;
- while (uio->uio_resid > 0) {
- int transfersize;
-
- chunksize = MIN(iov->iov_len, nmax);
-
- if (uio->uio_rw == UIO_READ) {
- struct fuse_read_in *fri;
-
- fdip->iosize = sizeof(struct fuse_read_in);
- fdisp_make_vp(fdip, op, vp, td, cred);
- fri = fdip->indata;
- fri->fh = fufh->fh_id;
- fri->offset = uio->uio_offset;
- fri->size = chunksize;
- fdip->tick->tk_aw_type = FT_A_BUF;
- fdip->tick->tk_aw_bufdata = iov->iov_base;
- } else {
- struct fuse_write_in *fwi;
-
- fdip->iosize = sizeof(struct fuse_write_in) + chunksize;
- fdisp_make_vp(fdip, op, vp, td, cred);
- fwi = fdip->indata;
- fwi->fh = fufh->fh_id;
- fwi->offset = uio->uio_offset;
- fwi->size = chunksize;
- fdip->tick->tk_ms_type = FT_M_BUF;
- fdip->tick->tk_ms_bufdata = iov->iov_base;
- fdip->tick->tk_ms_bufsize = chunksize;
- }
-
- DEBUG2G("chunksize %d\n", chunksize);
- fdip->finh->len = (sizeof *fdip->finh) + chunksize;
- err = fdisp_wait_answ(fdip);
-
- if (err)
- return (err);
-
- transfersize = (uio->uio_rw == UIO_READ) ?
- fdip->tick->tk_aw_ohead.len - sizeof(struct fuse_out_header) :
- ((struct fuse_write_out *)fdip->answ)->size;
-
- uio->uio_resid -= transfersize;
- uio->uio_offset += transfersize;
- iov->iov_len -= transfersize;
- iov->iov_base = (char *)iov->iov_base + transfersize;
-
- if (iov->iov_len == 0) {
- iov++;
- uio->uio_iovcnt--;
- }
- DEBUG2G("resid %zd, offset %ju, iovcnt %d, iov_len %zd, "
- "transfersize %d\n",
- uio->uio_resid, (uintmax_t)uio->uio_offset,
- uio->uio_iovcnt, iov->iov_len, transfersize);
-
- if (transfersize < chunksize)
- break;
- }
-
- return (0);
-}
-
/* Simple standard way for transmitting input */
static int
fuse_std_buffeater(struct uio *uio, size_t reqsize, void *buf, size_t bufsize, void *param)
@@ -434,13 +309,6 @@
fdisp_init(&fdi, 0);
- if (uio->uio_segflg == UIO_SYSSPACE) {
- if ((err = fuse_io_p2p(fioda, &fdi)))
- return (err);
- else
- goto out;
- }
-
while (uio->uio_resid > 0) {
chunksize = MIN(uio->uio_resid,
fuse_get_mpdata(vp->v_mount)->max_write);
@@ -470,21 +338,18 @@
uio->uio_offset -= diff;
}
-out:
fuse_ticket_drop(fdi.tick);
return (err);
}
-/*
- * Vnode op for write using bio
- */
static int
fuse_write_biobackend(struct fuse_io_data *fioda)
{
struct vnode *vp = fioda->vp;
struct uio *uio = fioda->uio;
struct ucred *cred = fioda->cred;
+ struct fuse_vnode_data *fvdat = VTOFUD(vp);
int biosize;
@@ -492,9 +357,8 @@
daddr_t lbn;
int bcount;
int n, on, err = 0;
- off_t fsize = VTOFUD(vp)->filesize;
- DEBUG2G("fsize %lld\n", (long long int)fsize);
+ DEBUG2G("fsize %ju\n", (uintmax_t)fvdat->filesize);
biosize = vp->v_mount->mnt_stat.f_iosize;
@@ -520,7 +384,7 @@
* unaligned buffer size.
*/
- if (uio->uio_offset == fsize && n) {
+ if (uio->uio_offset == fvdat->filesize && n) {
/*
* Get the buffer (in its pre-append state to maintain
* B_CACHE if it was previously set). Resize the
@@ -534,8 +398,7 @@
if (bp != NULL) {
long save;
- fsize = uio->uio_offset + n;
- fuse_vnode_setsize(vp, fsize);
+ fuse_vnode_setsize(vp, uio->uio_offset + n);
save = bp->b_flags & B_CACHE;
bcount += n;
@@ -548,17 +411,16 @@
* adjust the file's size as appropriate.
*/
bcount = on + n;
- if ((off_t)lbn * biosize + bcount < fsize) {
- if ((off_t)(lbn + 1) * biosize < fsize)
+ if ((off_t)lbn * biosize + bcount < fvdat->filesize) {
+ if ((off_t)(lbn + 1) * biosize < fvdat->filesize)
bcount = biosize;
else
- bcount = fsize - (off_t)lbn * biosize;
+ bcount = fvdat->filesize - (off_t)lbn * biosize;
}
DEBUG("getting block from OS, bcount %d\n", bcount);
bp = getblk(vp, lbn, bcount, PCATCH, 0, 0);
- if (uio->uio_offset + n > fsize) {
- fsize = uio->uio_offset + n;
- fuse_vnode_setsize(vp, fsize);
+ if (uio->uio_offset + n > fvdat->filesize) {
+ fuse_vnode_setsize(vp, uio->uio_offset + n);
}
}
@@ -596,7 +458,7 @@
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
fuse_io_strategy(vp, bp, NULL, 0);
- if ((err = bp->b_error)) {
+ if ((err = bp->b_error)) {
brelse(bp);
break;
}
@@ -614,7 +476,7 @@
*/
if (bp->b_dirtyend > bcount) {
- DEBUG2G("Fuse append race @%lx:%d\n",
+ DEBUG("Fuse append race @%lx:%d\n",
(long)bp->b_blkno * biosize,
bp->b_dirtyend - bcount);
bp->b_dirtyend = bcount;
@@ -696,7 +558,6 @@
return (err);
}
-/* core strategy like routine */
int
fuse_io_strategy(struct vnode *vp, struct buf *bp, struct fuse_filehandle *fufh,
enum fuse_opcode op)
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#8 (text+ko) ====
@@ -18,9 +18,7 @@
void *param;
};
-int fuse_io_dispatch(struct vnode *vp, struct uio *uio, int flag,
- struct ucred *cred);
-int fuse_io_vnode(struct vnode *vp, struct uio *uio, int ioflag,
+int fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
struct ucred *cred);
int fuse_io_strategy(struct vnode *vp, struct buf *bp,
struct fuse_filehandle *fufh, enum fuse_opcode op);
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#36 (text+ko) ====
@@ -1225,7 +1225,7 @@
return EIO;
}
- return fuse_io_vnode(vp, uio, ioflag, cred);
+ return fuse_io_dispatch(vp, uio, ioflag, cred);
}
/*
@@ -1827,23 +1827,10 @@
return EIO;
}
- return fuse_io_vnode(vp, uio, ioflag, cred);
+ return fuse_io_dispatch(vp, uio, ioflag, cred);
}
/*
- * [gs]etpages taken & stripped off from nfsclient
- */
-
-#ifndef PAGEOP_TRANSLATE_UIO
-#define PAGEOP_TRANSLATE_UIO 1
-#endif
-#if PAGEOP_TRANSLATE_UIO
-#define FUSE_PAGEOPS_RESID uio.uio_resid
-#else
-#define FUSE_PAGEOPS_RESID bp->b_resid
-#endif
-
-/*
struct vnop_getpages_args {
struct vnode *a_vp;
vm_page_t *a_m;
@@ -1856,10 +1843,8 @@
fuse_vnop_getpages(struct vop_getpages_args *ap)
{
int i, error, nextoff, size, toff, count, npages;
-#if PAGEOP_TRANSLATE_UIO
struct uio uio;
struct iovec iov;
-#endif
vm_offset_t kva;
struct buf *bp;
struct vnode *vp;
@@ -1889,28 +1874,22 @@
* can only occur at the file EOF.
*/
- {
- vm_page_t m = pages[ap->a_reqpage];
-
- VM_OBJECT_LOCK(vp->v_object);
- fuse_vm_page_lock_queues();
- if (m->valid != 0) {
- /* handled by vm_fault now */
- /* vm_page_zero_invalid(m, TRUE); */
- for (i = 0; i < npages; ++i) {
- if (i != ap->a_reqpage) {
- fuse_vm_page_lock(pages[i]);
- vm_page_free(pages[i]);
- fuse_vm_page_unlock(pages[i]);
- }
+ VM_OBJECT_LOCK(vp->v_object);
+ fuse_vm_page_lock_queues();
+ if (pages[ap->a_reqpage]->valid != 0) {
+ for (i = 0; i < npages; ++i) {
+ if (i != ap->a_reqpage) {
+ fuse_vm_page_lock(pages[i]);
+ vm_page_free(pages[i]);
+ fuse_vm_page_unlock(pages[i]);
}
- fuse_vm_page_unlock_queues();
- VM_OBJECT_UNLOCK(vp->v_object);
- return(0);
}
fuse_vm_page_unlock_queues();
VM_OBJECT_UNLOCK(vp->v_object);
+ return 0;
}
+ fuse_vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(vp->v_object);
/*
* We use only the kva address for the buffer, but this is extremely
@@ -1920,10 +1899,9 @@
kva = (vm_offset_t) bp->b_data;
pmap_qenter(kva, pages, npages);
- cnt.v_vnodein++;
- cnt.v_vnodepgsin += npages;
+ PCPU_INC(cnt.v_vnodein);
+ PCPU_ADD(cnt.v_vnodepgsin, npages);
-#if PAGEOP_TRANSLATE_UIO
iov.iov_base = (caddr_t) kva;
iov.iov_len = count;
uio.uio_iov = &iov;
@@ -1934,16 +1912,13 @@
uio.uio_rw = UIO_READ;
uio.uio_td = td;
- error = fuse_io_dispatch(vp, &uio, FREAD | O_DIRECT, cred);
-#else
- error = fuse_io_strategy(vp, bp);
-#endif
+ error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred);
pmap_qremove(kva, npages);
relpbuf(bp, &fuse_pbuf_freecnt);
- if (error && (FUSE_PAGEOPS_RESID == count)) {
- DEBUG2G("error %d\n", error);
+ if (error && (uio.uio_resid == count)) {
+ DEBUG("error %d\n", error);
VM_OBJECT_LOCK(vp->v_object);
fuse_vm_page_lock_queues();
for (i = 0; i < npages; ++i) {
@@ -1964,7 +1939,7 @@
* does not mean that the remaining data is invalid!
*/
- size = count - FUSE_PAGEOPS_RESID;
+ size = count - uio.uio_resid;
VM_OBJECT_LOCK(vp->v_object);
fuse_vm_page_lock_queues();
for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
@@ -1977,15 +1952,16 @@
* Read operation filled an entire page
*/
m->valid = VM_PAGE_BITS_ALL;
- vm_page_undirty(m);
+ KASSERT(m->dirty == 0,
+ ("fuse_getpages: page %p is dirty", m));
} else if (size > toff) {
/*
* Read operation filled a partial page.
*/
m->valid = 0;
- vm_page_set_validclean(m, 0, size - toff);
- /* handled by vm_fault now */
- /* vm_page_zero_invalid(m, TRUE); */
+ vm_page_set_valid(m, 0, size - toff);
+ KASSERT(m->dirty == 0,
+ ("fuse_getpages: page %p is dirty", m));
} else {
/*
* Read operation was short. If no error occured
@@ -2043,10 +2019,8 @@
static int
fuse_vnop_putpages(struct vop_putpages_args *ap)
{
-#if PAGEOP_TRANSLATE_UIO
struct uio uio;
struct iovec iov;
-#endif
vm_offset_t kva;
struct buf *bp;
int i, error, npages, count;
@@ -2096,10 +2070,9 @@
kva = (vm_offset_t) bp->b_data;
pmap_qenter(kva, pages, npages);
- cnt.v_vnodeout++;
- cnt.v_vnodepgsout += count;
+ PCPU_INC(cnt.v_vnodeout);
+ PCPU_ADD(cnt.v_vnodepgsout, count);
-#if PAGEOP_TRANSLATE_UIO
iov.iov_base = (caddr_t) kva;
iov.iov_len = count;
uio.uio_iov = &iov;
@@ -2110,16 +2083,13 @@
uio.uio_rw = UIO_WRITE;
uio.uio_td = td;
- error = fuse_io_dispatch(vp, &uio, FWRITE | O_DIRECT, cred);
-#else
- error = fuse_io_strategy(vp, bp);
-#endif
+ error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred);
pmap_qremove(kva, npages);
relpbuf(bp, &fuse_pbuf_freecnt);
if (!error) {
- int nwritten = round_page(count - FUSE_PAGEOPS_RESID) / PAGE_SIZE;
+ int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE;
for (i = 0; i < nwritten; i++) {
rtvals[i] = VM_PAGER_OK;
vm_page_undirty(pages[i]);
@@ -2127,7 +2097,6 @@
}
return rtvals[0];
}
-#undef FUSE_PAGEOPS_RESID
/*
struct vnop_print_args {
More information about the p4-projects
mailing list