From owner-p4-projects@FreeBSD.ORG Sat Jul 9 08:57:20 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 038BD1065670; Sat, 9 Jul 2011 08:57:20 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B8ED2106566B for ; Sat, 9 Jul 2011 08:57:19 +0000 (UTC) (envelope-from ilya@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id A615F8FC08 for ; Sat, 9 Jul 2011 08:57:19 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p698vJpO043194 for ; Sat, 9 Jul 2011 08:57:19 GMT (envelope-from ilya@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p698vJcw043191 for perforce@freebsd.org; Sat, 9 Jul 2011 08:57:19 GMT (envelope-from ilya@FreeBSD.org) Date: Sat, 9 Jul 2011 08:57:19 GMT Message-Id: <201107090857.p698vJcw043191@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to ilya@FreeBSD.org using -f From: Ilya Putsikau To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 195924 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Jul 2011 08:57:20 -0000 http://p4web.freebsd.org/@@195924?ac=10 Change 195924 by ilya@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 {