X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/96d24db91c8454b549fb47466f22b706255e93a5..68cdd7732293f306214db8a992fb213814ed6830:/sys/vfs/nfs/nfs_bio.c diff --git a/sys/vfs/nfs/nfs_bio.c b/sys/vfs/nfs/nfs_bio.c index 29cee4c619..e9dd4c8ee1 100644 --- a/sys/vfs/nfs/nfs_bio.c +++ b/sys/vfs/nfs/nfs_bio.c @@ -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 #include #include -#include #include #include @@ -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); }