kernel - Adjust UFS and HAMMER to use uiomovebp()
[dragonfly.git] / sys / vfs / nfs / nfs_bio.c
index 29cee4c..e9dd4c8 100644 (file)
@@ -35,7 +35,6 @@
  *
  *     @(#)nfs_bio.c   8.9 (Berkeley) 3/30/95
  * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_bio.c,v 1.130 2004/04/14 23:23:55 peadar Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_bio.c,v 1.45 2008/07/18 00:09:39 dillon Exp $
  */
 
 
@@ -49,7 +48,6 @@
 #include <sys/mount.h>
 #include <sys/kernel.h>
 #include <sys/mbuf.h>
-#include <sys/msfbuf.h>
 
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
@@ -400,11 +398,11 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag)
            switch (vp->v_type) {
            case VREG:
                if (n > 0)
-                   error = uiomove(bp->b_data + boff, n, uio);
+                   error = uiomovebp(bp, bp->b_data + boff, n, uio);
                break;
            case VLNK:
                if (n > 0)
-                   error = uiomove(bp->b_data + boff, n, uio);
+                   error = uiomovebp(bp, bp->b_data + boff, n, uio);
                n = 0;
                break;
            case VDIR:
@@ -507,13 +505,18 @@ nfs_write(struct vop_write_args *ap)
 #endif
        if (vp->v_type != VREG)
                return (EIO);
+
+       lwkt_gettoken(&nmp->nm_token);
+
        if (np->n_flag & NWRITEERR) {
                np->n_flag &= ~NWRITEERR;
+               lwkt_reltoken(&nmp->nm_token);
                return (np->n_error);
        }
        if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 &&
-           (nmp->nm_state & NFSSTA_GOTFSINFO) == 0)
+           (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
                (void)nfs_fsinfo(nmp, vp, td);
+       }
 
        /*
         * Synchronously flush pending buffers if we are in synchronous
@@ -525,7 +528,7 @@ nfs_write(struct vop_write_args *ap)
                        error = nfs_flush(vp, MNT_WAIT, td, 0);
                        /* error = nfs_vinvalbuf(vp, V_SAVE, 1); */
                        if (error)
-                               return (error);
+                               goto  done;
                }
        }
 
@@ -538,16 +541,22 @@ restart:
                np->n_attrstamp = 0;
                error = VOP_GETATTR(vp, &vattr);
                if (error)
-                       return (error);
+                       goto done;
                uio->uio_offset = np->n_size;
        }
 
-       if (uio->uio_offset < 0)
-               return (EINVAL);
-       if ((uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
-               return (EFBIG);
-       if (uio->uio_resid == 0)
-               return (0);
+       if (uio->uio_offset < 0) {
+               error = EINVAL;
+               goto done;
+       }
+       if ((uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize) {
+               error = EFBIG;
+               goto done;
+       }
+       if (uio->uio_resid == 0) {
+               error = 0;
+               goto done;
+       }
 
        /*
         * We need to obtain the rslock if we intend to modify np->n_size
@@ -571,7 +580,8 @@ restart:
                        /* not reached */
                case EINTR:
                case ERESTART:
-                       return(EINTR);
+                       error = EINTR;
+                       goto done;
                        /* not reached */
                default:
                        break;
@@ -588,7 +598,8 @@ restart:
                lwpsignal(td->td_proc, td->td_lwp, SIGXFSZ);
                if (haverslock)
                        nfs_rsunlock(np);
-               return (EFBIG);
+               error = EFBIG;
+               goto done;
        }
 
        biosize = vp->v_mount->mnt_stat.f_iosize;
@@ -711,7 +722,7 @@ again:
                        goto again;
                }
 
-               error = uiomove(bp->b_data + boff, bytes, uio);
+               error = uiomovebp(bp, bp->b_data + boff, bytes, uio);
 
                /*
                 * Since this block is being modified, it must be written
@@ -774,6 +785,8 @@ again:
        if (haverslock)
                nfs_rsunlock(np);
 
+done:
+       lwkt_reltoken(&nmp->nm_token);
        return (error);
 }
 
@@ -910,6 +923,14 @@ nfs_asyncio(struct vnode *vp, struct bio *bio)
 
        KKASSERT(vp->v_tag == VT_NFS);
        BUF_KERNPROC(bp);
+
+       /*
+        * Shortcut swap cache (not done automatically because we are not
+        * using bread()).
+        */
+       if (vn_cache_strategy(vp, bio))
+               return;
+
        bio->bio_driver_info = vp;
        crit_enter();
        TAILQ_INSERT_TAIL(&nmp->nm_bioq, bio, bio_act);
@@ -919,7 +940,7 @@ nfs_asyncio(struct vnode *vp, struct bio *bio)
 }
 
 /*
- * nfs_dio()   - Execute a BIO operation synchronously.  The BIO will be
+ * nfs_doio()  - Execute a BIO operation synchronously.  The BIO will be
  *               completed and its error returned.  The caller is responsible
  *               for brelse()ing it.  ONLY USE FOR BIO_SYNC IOs!  Otherwise
  *               our error probe will be against an invalid pointer.
@@ -1021,6 +1042,24 @@ nfs_doio(struct vnode *vp, struct bio *bio, struct thread *td)
        struct uio uio;
        struct iovec io;
 
+#if 0
+       /*
+        * Shortcut swap cache (not done automatically because we are not
+        * using bread()).
+        *
+        * XXX The biowait is a hack until we can figure out how to stop a
+        * biodone chain when a middle element is BIO_SYNC.  BIO_SYNC is
+        * set so the bp shouldn't get ripped out from under us.  The only
+        * use-cases are fully synchronous I/O cases.
+        *
+        * XXX This is having problems, give up for now.
+        */
+       if (vn_cache_strategy(vp, bio)) {
+               error = biowait(&bio->bio_buf->b_bio1, "nfsrsw");
+               return (error);
+       }
+#endif
+
        KKASSERT(vp->v_tag == VT_NFS);
        np = VTONFS(vp);
        nmp = VFSTONFS(vp->v_mount);
@@ -1250,10 +1289,11 @@ nfs_meta_setsize(struct vnode *vp, struct thread *td, off_t nsize, int trivial)
        np->n_size = nsize;
 
        if (nsize < osize) {
-               error = nvtruncbuf(vp, nsize, biosize);
+               error = nvtruncbuf(vp, nsize, biosize, -1);
        } else {
                error = nvextendbuf(vp, osize, nsize,
-                                   biosize, biosize, trivial);
+                                   biosize, biosize, -1, -1,
+                                   trivial);
        }
        return(error);
 }
@@ -1332,6 +1372,8 @@ nfs_readrpc_bio_done(nfsm_info_t info)
 
        KKASSERT(info->state == NFSM_STATE_DONE);
 
+       lwkt_gettoken(&nmp->nm_token);
+
        if (info->v3) {
                ERROROUT(nfsm_postop_attr(info, info->vp, &attrflag,
                                         NFS_LATTR_NOSHRINK));
@@ -1370,6 +1412,7 @@ nfs_readrpc_bio_done(nfsm_info_t info)
        bp->b_resid = 0;
        /* bp->b_resid = bp->b_bcount - retlen; */
 nfsmout:
+       lwkt_reltoken(&nmp->nm_token);
        kfree(info, M_NFSREQ);
        if (error) {
                bp->b_error = error;
@@ -1482,6 +1525,8 @@ nfs_writerpc_bio_done(nfsm_info_t info)
        int len = bp->b_resid;  /* b_resid was set to shortened length */
        u_int32_t *tl;
 
+       lwkt_gettoken(&nmp->nm_token);
+
        if (info->v3) {
                /*
                 * The write RPC returns a before and after mtime.  The
@@ -1597,6 +1642,8 @@ nfsmout:
        }
        if (info->info_writerpc.must_commit)
                nfs_clearcommit(info->vp->v_mount);
+       lwkt_reltoken(&nmp->nm_token);
+
        kfree(info, M_NFSREQ);
        if (error) {
                bp->b_flags |= B_ERROR;
@@ -1662,6 +1709,8 @@ nfs_commitrpc_bio_done(nfsm_info_t info)
        int wccflag = NFSV3_WCCRATTR;
        int error = 0;
 
+       lwkt_gettoken(&nmp->nm_token);
+
        ERROROUT(nfsm_wcc_data(info, info->vp, &wccflag));
        if (error == 0) {
                NULLOUT(tl = nfsm_dissect(info, NFSX_V3WRITEVERF));
@@ -1678,7 +1727,6 @@ nfs_commitrpc_bio_done(nfsm_info_t info)
         * error occurred.
         */
 nfsmout:
-       kfree(info, M_NFSREQ);
        if (error == 0) {
                bp->b_dirtyoff = bp->b_dirtyend = 0;
                bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
@@ -1687,5 +1735,7 @@ nfsmout:
        } else {
                nfs_writerpc_bio(info->vp, bio);
        }
+       kfree(info, M_NFSREQ);
+       lwkt_reltoken(&nmp->nm_token);
 }