diff --git a/sys/fs/nfs/nfs_commonport.c.direct b/sys/fs/nfs/nfs_commonport.c --- a/sys/fs/nfs/nfs_commonport.c.direct +++ b/sys/fs/nfs/nfs_commonport.c @@ -123,7 +123,6 @@ MALLOC_DEFINE(M_NEWNFSCLLOCKOWNER, "NFSCL lckown", "NFSCL Lock Owner"); MALLOC_DEFINE(M_NEWNFSCLLOCK, "NFSCL lck", "NFSCL Lock"); MALLOC_DEFINE(M_NEWNFSV4NODE, "NEWNFSnode", "NFS vnode"); -MALLOC_DEFINE(M_NEWNFSDIRECTIO, "NEWdirectio", "NFS Direct IO buffer"); MALLOC_DEFINE(M_NEWNFSDIROFF, "NFSCL diroff", "NFS directory offset data"); MALLOC_DEFINE(M_NEWNFSDROLLBACK, "NFSD rollback", diff --git a/sys/fs/nfs/nfsport.h.direct b/sys/fs/nfs/nfsport.h --- a/sys/fs/nfs/nfsport.h.direct +++ b/sys/fs/nfs/nfsport.h @@ -943,7 +943,6 @@ MALLOC_DECLARE(M_NEWNFSCLLOCK); MALLOC_DECLARE(M_NEWNFSDIROFF); MALLOC_DECLARE(M_NEWNFSV4NODE); -MALLOC_DECLARE(M_NEWNFSDIRECTIO); MALLOC_DECLARE(M_NEWNFSMNT); MALLOC_DECLARE(M_NEWNFSDROLLBACK); MALLOC_DECLARE(M_NEWNFSLAYOUT); @@ -970,7 +969,6 @@ #define M_NFSCLLOCK M_NEWNFSCLLOCK #define M_NFSDIROFF M_NEWNFSDIROFF #define M_NFSV4NODE M_NEWNFSV4NODE -#define M_NFSDIRECTIO M_NEWNFSDIRECTIO #define M_NFSDROLLBACK M_NEWNFSDROLLBACK #define M_NFSLAYOUT M_NEWNFSLAYOUT #define M_NFSFLAYOUT M_NEWNFSFLAYOUT diff --git a/sys/fs/nfsclient/nfs_clbio.c.direct b/sys/fs/nfsclient/nfs_clbio.c --- a/sys/fs/nfsclient/nfs_clbio.c.direct +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -755,144 +755,58 @@ nfs_directio_write(struct vnode *vp, struct uio *uiop, struct ucred *cred, int ioflag) { - int error; + struct uio uio; + struct iovec iov; struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct thread *td = uiop->uio_td; - int size; - int wsize; + int error, iomode, must_commit, size, wsize; + KASSERT((ioflag & IO_SYNC) != 0, ("nfs_directio_write: not sync")); mtx_lock(&nmp->nm_mtx); wsize = nmp->nm_wsize; mtx_unlock(&nmp->nm_mtx); - if (ioflag & IO_SYNC) { - int iomode, must_commit; - struct uio uio; - struct iovec iov; -do_sync: - while (uiop->uio_resid > 0) { - size = MIN(uiop->uio_resid, wsize); - size = MIN(uiop->uio_iov->iov_len, size); - iov.iov_base = uiop->uio_iov->iov_base; - iov.iov_len = size; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = uiop->uio_offset; - uio.uio_resid = size; - uio.uio_segflg = uiop->uio_segflg; - uio.uio_rw = UIO_WRITE; - uio.uio_td = td; - iomode = NFSWRITE_FILESYNC; - /* - * When doing direct I/O we do not care if the - * server's write verifier has changed, but we - * do not want to update the verifier if it has - * changed, since that hides the change from - * writes being done through the buffer cache. - * By passing must_commit in set to two, the code - * in nfsrpc_writerpc() will not update the - * verifier on the mount point. - */ - must_commit = 2; - error = ncl_writerpc(vp, &uio, cred, &iomode, - &must_commit, 0, ioflag); - KASSERT((must_commit == 2), - ("ncl_directio_write: Updated write verifier")); - if (error) - return (error); - if (iomode != NFSWRITE_FILESYNC) - printf("nfs_directio_write: Broken server " - "did not reply FILE_SYNC\n"); - uiop->uio_offset += size; - uiop->uio_resid -= size; - if (uiop->uio_iov->iov_len <= size) { - uiop->uio_iovcnt--; - uiop->uio_iov++; - } else { - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + size; - uiop->uio_iov->iov_len -= size; - } - } - } else { - struct uio *t_uio; - struct iovec *t_iov; - struct buf *bp; - + while (uiop->uio_resid > 0) { + size = MIN(uiop->uio_resid, wsize); + size = MIN(uiop->uio_iov->iov_len, size); + iov.iov_base = uiop->uio_iov->iov_base; + iov.iov_len = size; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_offset = uiop->uio_offset; + uio.uio_resid = size; + uio.uio_segflg = uiop->uio_segflg; + uio.uio_rw = UIO_WRITE; + uio.uio_td = td; + iomode = NFSWRITE_FILESYNC; /* - * Break up the write into blocksize chunks and hand these - * over to nfsiod's for write back. - * Unfortunately, this incurs a copy of the data. Since - * the user could modify the buffer before the write is - * initiated. - * - * The obvious optimization here is that one of the 2 copies - * in the async write path can be eliminated by copying the - * data here directly into mbufs and passing the mbuf chain - * down. But that will require a fair amount of re-working - * of the code and can be done if there's enough interest - * in NFS directio access. + * When doing direct I/O we do not care if the + * server's write verifier has changed, but we + * do not want to update the verifier if it has + * changed, since that hides the change from + * writes being done through the buffer cache. + * By passing must_commit in set to two, the code + * in nfsrpc_writerpc() will not update the + * verifier on the mount point. */ - while (uiop->uio_resid > 0) { - size = MIN(uiop->uio_resid, wsize); - size = MIN(uiop->uio_iov->iov_len, size); - bp = uma_zalloc(ncl_pbuf_zone, M_WAITOK); - t_uio = malloc(sizeof(struct uio), M_NFSDIRECTIO, M_WAITOK); - t_iov = malloc(sizeof(struct iovec), M_NFSDIRECTIO, M_WAITOK); - t_iov->iov_base = malloc(size, M_NFSDIRECTIO, M_WAITOK); - t_iov->iov_len = size; - t_uio->uio_iov = t_iov; - t_uio->uio_iovcnt = 1; - t_uio->uio_offset = uiop->uio_offset; - t_uio->uio_resid = size; - t_uio->uio_segflg = UIO_SYSSPACE; - t_uio->uio_rw = UIO_WRITE; - t_uio->uio_td = td; - KASSERT(uiop->uio_segflg == UIO_USERSPACE || - uiop->uio_segflg == UIO_SYSSPACE, - ("nfs_directio_write: Bad uio_segflg")); - if (uiop->uio_segflg == UIO_USERSPACE) { - error = copyin(uiop->uio_iov->iov_base, - t_iov->iov_base, size); - if (error != 0) - goto err_free; - } else - /* - * UIO_SYSSPACE may never happen, but handle - * it just in case it does. - */ - bcopy(uiop->uio_iov->iov_base, t_iov->iov_base, - size); - bp->b_flags |= B_DIRECT; - bp->b_iocmd = BIO_WRITE; - if (cred != NOCRED) { - crhold(cred); - bp->b_wcred = cred; - } else - bp->b_wcred = NOCRED; - bp->b_caller1 = (void *)t_uio; - bp->b_vp = vp; - error = ncl_asyncio(nmp, bp, NOCRED, td); -err_free: - if (error) { - free(t_iov->iov_base, M_NFSDIRECTIO); - free(t_iov, M_NFSDIRECTIO); - free(t_uio, M_NFSDIRECTIO); - bp->b_vp = NULL; - uma_zfree(ncl_pbuf_zone, bp); - if (error == EINTR) - return (error); - goto do_sync; - } - uiop->uio_offset += size; - uiop->uio_resid -= size; - if (uiop->uio_iov->iov_len <= size) { - uiop->uio_iovcnt--; - uiop->uio_iov++; - } else { - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + size; - uiop->uio_iov->iov_len -= size; - } + must_commit = 2; + error = ncl_writerpc(vp, &uio, cred, &iomode, + &must_commit, 0, ioflag); + KASSERT((must_commit == 2), + ("ncl_directio_write: Updated write verifier")); + if (error) + return (error); + if (iomode != NFSWRITE_FILESYNC) + printf("nfs_directio_write: Broken server " + "did not reply FILE_SYNC\n"); + uiop->uio_offset += size; + uiop->uio_resid -= size; + if (uiop->uio_iov->iov_len <= size) { + uiop->uio_iovcnt--; + uiop->uio_iov++; + } else { + uiop->uio_iov->iov_base = + (char *)uiop->uio_iov->iov_base + size; + uiop->uio_iov->iov_len -= size; } } return (0); @@ -1464,7 +1378,7 @@ nanouptime(&ts); NFSLOCKNODE(np); } - if (np->n_directio_asyncwr == 0 && (np->n_flag & NMODIFIED) != 0) { + if ((np->n_flag & NMODIFIED) != 0) { np->n_localmodtime = ts; np->n_flag &= ~NMODIFIED; } @@ -1609,12 +1523,6 @@ BUF_KERNPROC(bp); TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist); nmp->nm_bufqlen++; - if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) { - NFSLOCKNODE(VTONFS(bp->b_vp)); - VTONFS(bp->b_vp)->n_flag |= NMODIFIED; - VTONFS(bp->b_vp)->n_directio_asyncwr++; - NFSUNLOCKNODE(VTONFS(bp->b_vp)); - } NFSUNLOCKIOD(); return (0); } @@ -1627,60 +1535,6 @@ */ NFS_DPF(ASYNCIO, ("ncl_asyncio: no iods available, i/o is synchronous\n")); return (EIO); -} - -void -ncl_doio_directwrite(struct buf *bp) -{ - int iomode, must_commit; - struct uio *uiop = (struct uio *)bp->b_caller1; - char *iov_base = uiop->uio_iov->iov_base; - - panic("ncl_doio_directwrite called!!"); - iomode = NFSWRITE_FILESYNC; - uiop->uio_td = NULL; /* NULL since we're in nfsiod */ - /* - * When doing direct I/O we do not care if the - * server's write verifier has changed, but we - * do not want to update the verifier if it has - * changed, since that hides the change from - * writes being done through the buffer cache. - * By passing must_commit in set to two, the code - * in nfsrpc_writerpc() will not update the - * verifier on the mount point. - */ - must_commit = 2; - ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit, 0, 0); - KASSERT((must_commit == 2), ("ncl_doio_directwrite: Updated write" - " verifier")); - if (iomode != NFSWRITE_FILESYNC) - printf("ncl_doio_directwrite: Broken server " - "did not reply FILE_SYNC\n"); - free(iov_base, M_NFSDIRECTIO); - free(uiop->uio_iov, M_NFSDIRECTIO); - free(uiop, M_NFSDIRECTIO); - if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) { - struct nfsnode *np = VTONFS(bp->b_vp); - NFSLOCKNODE(np); - if (NFSHASPNFS(VFSTONFS(bp->b_vp->v_mount))) { - /* - * Invalidate the attribute cache, since writes to a DS - * won't update the size attribute. - */ - np->n_attrstamp = 0; - } - np->n_directio_asyncwr--; - if (np->n_directio_asyncwr == 0) { - np->n_flag &= ~NMODIFIED; - if ((np->n_flag & NFSYNCWAIT)) { - np->n_flag &= ~NFSYNCWAIT; - wakeup((caddr_t)&np->n_directio_asyncwr); - } - } - NFSUNLOCKNODE(np); - } - bp->b_vp = NULL; - uma_zfree(ncl_pbuf_zone, bp); } /* diff --git a/sys/fs/nfsclient/nfs_clnfsiod.c.direct b/sys/fs/nfsclient/nfs_clnfsiod.c --- a/sys/fs/nfsclient/nfs_clnfsiod.c.direct +++ b/sys/fs/nfsclient/nfs_clnfsiod.c @@ -294,17 +294,12 @@ wakeup(&nmp->nm_bufq); } NFSUNLOCKIOD(); - if (bp->b_flags & B_DIRECT) { - KASSERT((bp->b_iocmd == BIO_WRITE), ("nfscvs_iod: BIO_WRITE not set")); - (void)ncl_doio_directwrite(bp); - } else { - if (bp->b_iocmd == BIO_READ) - (void) ncl_doio(bp->b_vp, bp, bp->b_rcred, - NULL, 0); - else - (void) ncl_doio(bp->b_vp, bp, bp->b_wcred, - NULL, 0); - } + if (bp->b_iocmd == BIO_READ) + (void) ncl_doio(bp->b_vp, bp, bp->b_rcred, + NULL, 0); + else + (void) ncl_doio(bp->b_vp, bp, bp->b_wcred, + NULL, 0); NFSLOCKIOD(); /* * Make sure the nmp hasn't been dismounted as soon as diff --git a/sys/fs/nfsclient/nfs_clvnops.c.direct b/sys/fs/nfsclient/nfs_clvnops.c --- a/sys/fs/nfsclient/nfs_clvnops.c.direct +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -982,10 +982,6 @@ NFSUNLOCKNODE(np); } } - if (newnfs_directio_enable) - KASSERT((np->n_directio_asyncwr == 0), - ("nfs_close: dirty unflushed (%d) directio buffers\n", - np->n_directio_asyncwr)); if (newnfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) { NFSLOCKNODE(np); KASSERT((np->n_directio_opens > 0), @@ -3378,21 +3374,6 @@ * Wait for all the async IO requests to drain */ BO_UNLOCK(bo); - NFSLOCKNODE(np); - while (np->n_directio_asyncwr > 0) { - np->n_flag |= NFSYNCWAIT; - error = newnfs_msleep(td, &np->n_directio_asyncwr, - &np->n_mtx, slpflag | (PRIBIO + 1), - "nfsfsync", 0); - if (error) { - if (newnfs_sigintr(nmp, td)) { - NFSUNLOCKNODE(np); - error = EINTR; - goto done; - } - } - } - NFSUNLOCKNODE(np); } else BO_UNLOCK(bo); if (NFSHASPNFS(nmp)) { @@ -3410,15 +3391,14 @@ np->n_flag &= ~NWRITEERR; } if (commit && bo->bo_dirty.bv_cnt == 0 && - bo->bo_numoutput == 0 && np->n_directio_asyncwr == 0) + bo->bo_numoutput == 0) np->n_flag &= ~NMODIFIED; NFSUNLOCKNODE(np); done: if (bvec != NULL && bvec != bvec_on_stack) free(bvec, M_TEMP); if (error == 0 && commit != 0 && waitfor == MNT_WAIT && - (bo->bo_dirty.bv_cnt != 0 || bo->bo_numoutput != 0 || - np->n_directio_asyncwr != 0)) { + (bo->bo_dirty.bv_cnt != 0 || bo->bo_numoutput != 0)) { if (trycnt++ < 5) { /* try, try again... */ passone = 1; diff --git a/sys/fs/nfsclient/nfsnode.h.direct b/sys/fs/nfsclient/nfsnode.h --- a/sys/fs/nfsclient/nfsnode.h.direct +++ b/sys/fs/nfsclient/nfsnode.h @@ -124,7 +124,6 @@ short n_fhsize; /* size in bytes, of fh */ u_int32_t n_flag; /* Flag for locking.. */ int n_directio_opens; - int n_directio_asyncwr; u_int64_t n_change; /* old Change attribute */ struct nfsv4node *n_v4; /* extra V4 stuff */ struct ucred *n_writecred; /* Cred. for putpages */ @@ -146,8 +145,6 @@ * Flags for n_flag */ #define NDIRCOOKIELK 0x00000001 /* Lock to serialize access to directory cookies */ -#define NFSYNCWAIT 0x00000002 /* fsync waiting for all directio async - writes to drain */ #define NMODIFIED 0x00000004 /* Might have a modified buffer in bio */ #define NWRITEERR 0x00000008 /* Flag write errors so close will know */ #define NCREATED 0x00000010 /* Opened by nfs_create() */