Author: kib
Date: Tue Mar 19 15:08:15 2013
New Revision: 248521
URL: http://svnweb.freebsd.org/changeset/base/248521

Log:
  UFS support of the unmapped i/o for the user data buffers.
  
  Sponsored by: The FreeBSD Foundation
  Tested by:    pho, scottl, jhb, bf

Modified:
  head/sys/ufs/ffs/ffs_alloc.c
  head/sys/ufs/ffs/ffs_balloc.c
  head/sys/ufs/ffs/ffs_vfsops.c
  head/sys/ufs/ffs/ffs_vnops.c
  head/sys/ufs/ufs/ufs_extern.h

Modified: head/sys/ufs/ffs/ffs_alloc.c
==============================================================================
--- head/sys/ufs/ffs/ffs_alloc.c        Tue Mar 19 15:05:21 2013        
(r248520)
+++ head/sys/ufs/ffs/ffs_alloc.c        Tue Mar 19 15:08:15 2013        
(r248521)
@@ -254,7 +254,7 @@ ffs_realloccg(ip, lbprev, bprev, bpref, 
        struct buf *bp;
        struct ufsmount *ump;
        u_int cg, request, reclaimed;
-       int error;
+       int error, gbflags;
        ufs2_daddr_t bno;
        static struct timeval lastfail;
        static int curfail;
@@ -265,6 +265,8 @@ ffs_realloccg(ip, lbprev, bprev, bpref, 
        fs = ip->i_fs;
        bp = NULL;
        ump = ip->i_ump;
+       gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
+
        mtx_assert(UFS_MTX(ump), MA_OWNED);
 #ifdef INVARIANTS
        if (vp->v_mount->mnt_kern_flag & MNTK_SUSPENDED)
@@ -296,7 +298,7 @@ retry:
        /*
         * Allocate the extra space in the buffer.
         */
-       error = bread(vp, lbprev, osize, NOCRED, &bp);
+       error = bread_gb(vp, lbprev, osize, NOCRED, gbflags, &bp);
        if (error) {
                brelse(bp);
                return (error);
@@ -332,7 +334,7 @@ retry:
                        ip->i_flag |= IN_CHANGE | IN_UPDATE;
                allocbuf(bp, nsize);
                bp->b_flags |= B_DONE;
-               bzero(bp->b_data + osize, nsize - osize);
+               vfs_bio_bzero_buf(bp, osize, nsize - osize);
                if ((bp->b_flags & (B_MALLOC | B_VMIO)) == B_VMIO)
                        vfs_bio_set_valid(bp, osize, nsize - osize);
                *bpp = bp;
@@ -400,7 +402,7 @@ retry:
                        ip->i_flag |= IN_CHANGE | IN_UPDATE;
                allocbuf(bp, nsize);
                bp->b_flags |= B_DONE;
-               bzero(bp->b_data + osize, nsize - osize);
+               vfs_bio_bzero_buf(bp, osize, nsize - osize);
                if ((bp->b_flags & (B_MALLOC | B_VMIO)) == B_VMIO)
                        vfs_bio_set_valid(bp, osize, nsize - osize);
                *bpp = bp;

Modified: head/sys/ufs/ffs/ffs_balloc.c
==============================================================================
--- head/sys/ufs/ffs/ffs_balloc.c       Tue Mar 19 15:05:21 2013        
(r248520)
+++ head/sys/ufs/ffs/ffs_balloc.c       Tue Mar 19 15:08:15 2013        
(r248521)
@@ -107,7 +107,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
        int saved_inbdflush;
        static struct timeval lastfail;
        static int curfail;
-       int reclaimed;
+       int gbflags, reclaimed;
 
        ip = VTOI(vp);
        dp = ip->i_din1;
@@ -123,6 +123,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
                return (EOPNOTSUPP);
        if (lbn < 0)
                return (EFBIG);
+       gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
 
        if (DOINGSOFTDEP(vp))
                softdep_prealloc(vp, MNT_WAIT);
@@ -211,7 +212,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
                            nsize, flags, cred, &newb);
                        if (error)
                                return (error);
-                       bp = getblk(vp, lbn, nsize, 0, 0, 0);
+                       bp = getblk(vp, lbn, nsize, 0, 0, gbflags);
                        bp->b_blkno = fsbtodb(fs, newb);
                        if (flags & BA_CLRBUF)
                                vfs_bio_clrbuf(bp);
@@ -255,7 +256,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = indirs[1].in_lbn;
-               bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, 0);
+               bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, gbflags);
                bp->b_blkno = fsbtodb(fs, nb);
                vfs_bio_clrbuf(bp);
                if (DOINGSOFTDEP(vp)) {
@@ -389,7 +390,7 @@ retry:
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = lbn;
-               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
+               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, gbflags);
                nbp->b_blkno = fsbtodb(fs, nb);
                if (flags & BA_CLRBUF)
                        vfs_bio_clrbuf(nbp);
@@ -418,16 +419,17 @@ retry:
                if (seqcount && (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
                        error = cluster_read(vp, ip->i_size, lbn,
                            (int)fs->fs_bsize, NOCRED,
-                           MAXBSIZE, seqcount, 0, &nbp);
+                           MAXBSIZE, seqcount, gbflags, &nbp);
                } else {
-                       error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
+                       error = bread_gb(vp, lbn, (int)fs->fs_bsize, NOCRED,
+                           gbflags, &nbp);
                }
                if (error) {
                        brelse(nbp);
                        goto fail;
                }
        } else {
-               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
+               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, gbflags);
                nbp->b_blkno = fsbtodb(fs, nb);
        }
        curthread_pflags_restore(saved_inbdflush);
@@ -539,7 +541,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
        int saved_inbdflush;
        static struct timeval lastfail;
        static int curfail;
-       int reclaimed;
+       int gbflags, reclaimed;
 
        ip = VTOI(vp);
        dp = ip->i_din2;
@@ -553,6 +555,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
        *bpp = NULL;
        if (lbn < 0)
                return (EFBIG);
+       gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
 
        if (DOINGSOFTDEP(vp))
                softdep_prealloc(vp, MNT_WAIT);
@@ -603,7 +606,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                        panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
                nb = dp->di_extb[lbn];
                if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) {
-                       error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp);
+                       error = bread_gb(vp, -1 - lbn, fs->fs_bsize, NOCRED,
+                           gbflags, &bp);
                        if (error) {
                                brelse(bp);
                                return (error);
@@ -620,7 +624,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                        osize = fragroundup(fs, blkoff(fs, dp->di_extsize));
                        nsize = fragroundup(fs, size);
                        if (nsize <= osize) {
-                               error = bread(vp, -1 - lbn, osize, NOCRED, &bp);
+                               error = bread_gb(vp, -1 - lbn, osize, NOCRED,
+                                   gbflags, &bp);
                                if (error) {
                                        brelse(bp);
                                        return (error);
@@ -653,7 +658,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                           nsize, flags, cred, &newb);
                        if (error)
                                return (error);
-                       bp = getblk(vp, -1 - lbn, nsize, 0, 0, 0);
+                       bp = getblk(vp, -1 - lbn, nsize, 0, 0, gbflags);
                        bp->b_blkno = fsbtodb(fs, newb);
                        bp->b_xflags |= BX_ALTDATA;
                        if (flags & BA_CLRBUF)
@@ -707,7 +712,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                        panic("ffs_balloc_ufs2: BA_METAONLY for direct block");
                nb = dp->di_db[lbn];
                if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
-                       error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
+                       error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED,
+                           gbflags, &bp);
                        if (error) {
                                brelse(bp);
                                return (error);
@@ -723,7 +729,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                        osize = fragroundup(fs, blkoff(fs, ip->i_size));
                        nsize = fragroundup(fs, size);
                        if (nsize <= osize) {
-                               error = bread(vp, lbn, osize, NOCRED, &bp);
+                               error = bread_gb(vp, lbn, osize, NOCRED,
+                                   gbflags, &bp);
                                if (error) {
                                        brelse(bp);
                                        return (error);
@@ -753,7 +760,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                                &dp->di_db[0]), nsize, flags, cred, &newb);
                        if (error)
                                return (error);
-                       bp = getblk(vp, lbn, nsize, 0, 0, 0);
+                       bp = getblk(vp, lbn, nsize, 0, 0, gbflags);
                        bp->b_blkno = fsbtodb(fs, newb);
                        if (flags & BA_CLRBUF)
                                vfs_bio_clrbuf(bp);
@@ -797,7 +804,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = indirs[1].in_lbn;
-               bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, 0);
+               bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0,
+                   GB_UNMAPPED);
                bp->b_blkno = fsbtodb(fs, nb);
                vfs_bio_clrbuf(bp);
                if (DOINGSOFTDEP(vp)) {
@@ -862,7 +870,8 @@ retry:
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = indirs[i].in_lbn;
-               nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, 0);
+               nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0,
+                   GB_UNMAPPED);
                nbp->b_blkno = fsbtodb(fs, nb);
                vfs_bio_clrbuf(nbp);
                if (DOINGSOFTDEP(vp)) {
@@ -931,7 +940,7 @@ retry:
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = lbn;
-               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
+               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, gbflags);
                nbp->b_blkno = fsbtodb(fs, nb);
                if (flags & BA_CLRBUF)
                        vfs_bio_clrbuf(nbp);
@@ -966,16 +975,17 @@ retry:
                if (seqcount && (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
                        error = cluster_read(vp, ip->i_size, lbn,
                            (int)fs->fs_bsize, NOCRED,
-                           MAXBSIZE, seqcount, 0, &nbp);
+                           MAXBSIZE, seqcount, gbflags, &nbp);
                } else {
-                       error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
+                       error = bread_gb(vp, lbn, (int)fs->fs_bsize,
+                           NOCRED, gbflags, &nbp);
                }
                if (error) {
                        brelse(nbp);
                        goto fail;
                }
        } else {
-               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
+               nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, gbflags);
                nbp->b_blkno = fsbtodb(fs, nb);
        }
        curthread_pflags_restore(saved_inbdflush);

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c       Tue Mar 19 15:05:21 2013        
(r248520)
+++ head/sys/ufs/ffs/ffs_vfsops.c       Tue Mar 19 15:08:15 2013        
(r248521)
@@ -1076,7 +1076,7 @@ ffs_mountfs(devvp, mp, td)
         */
        MNT_ILOCK(mp);
        mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED |
-           MNTK_NO_IOPF;
+           MNTK_NO_IOPF | MNTK_UNMAPPED_BUFS;
        MNT_IUNLOCK(mp);
 #ifdef UFS_EXTATTR
 #ifdef UFS_EXTATTR_AUTOSTART
@@ -2110,6 +2110,7 @@ ffs_bufwrite(struct buf *bp)
                 * set b_lblkno and BKGRDMARKER before calling bgetvp()
                 * to avoid confusing the splay tree and gbincore().
                 */
+               KASSERT((bp->b_flags & B_UNMAPPED) == 0, ("Unmapped cg"));
                memcpy(newbp->b_data, bp->b_data, bp->b_bufsize);
                newbp->b_lblkno = bp->b_lblkno;
                newbp->b_xflags |= BX_BKGRDMARKER;

Modified: head/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vnops.c        Tue Mar 19 15:05:21 2013        
(r248520)
+++ head/sys/ufs/ffs/ffs_vnops.c        Tue Mar 19 15:08:15 2013        
(r248521)
@@ -509,7 +509,8 @@ ffs_read(ap)
                        /*
                         * Don't do readahead if this is the end of the file.
                         */
-                       error = bread(vp, lbn, size, NOCRED, &bp);
+                       error = bread_gb(vp, lbn, size, NOCRED,
+                           GB_UNMAPPED, &bp);
                } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
                        /*
                         * Otherwise if we are allowed to cluster,
@@ -520,7 +521,7 @@ ffs_read(ap)
                         */
                        error = cluster_read(vp, ip->i_size, lbn,
                            size, NOCRED, blkoffset + uio->uio_resid,
-                           seqcount, 0, &bp);
+                           seqcount, GB_UNMAPPED, &bp);
                } else if (seqcount > 1) {
                        /*
                         * If we are NOT allowed to cluster, then
@@ -531,15 +532,16 @@ ffs_read(ap)
                         * the 6th argument.
                         */
                        int nextsize = blksize(fs, ip, nextlbn);
-                       error = breadn(vp, lbn,
-                           size, &nextlbn, &nextsize, 1, NOCRED, &bp);
+                       error = breadn_flags(vp, lbn, size, &nextlbn,
+                           &nextsize, 1, NOCRED, GB_UNMAPPED, &bp);
                } else {
                        /*
                         * Failing all of the above, just read what the
                         * user asked for. Interestingly, the same as
                         * the first option above.
                         */
-                       error = bread(vp, lbn, size, NOCRED, &bp);
+                       error = bread_gb(vp, lbn, size, NOCRED,
+                           GB_UNMAPPED, &bp);
                }
                if (error) {
                        brelse(bp);
@@ -570,8 +572,13 @@ ffs_read(ap)
                        xfersize = size;
                }
 
-               error = vn_io_fault_uiomove((char *)bp->b_data + blkoffset,
-                   (int)xfersize, uio);
+               if ((bp->b_flags & B_UNMAPPED) == 0) {
+                       error = vn_io_fault_uiomove((char *)bp->b_data +
+                           blkoffset, (int)xfersize, uio);
+               } else {
+                       error = vn_io_fault_pgmove(bp->b_pages, blkoffset,
+                           (int)xfersize, uio);
+               }
                if (error)
                        break;
 
@@ -702,6 +709,7 @@ ffs_write(ap)
                flags = seqcount << BA_SEQSHIFT;
        if ((ioflag & IO_SYNC) && !DOINGASYNC(vp))
                flags |= IO_SYNC;
+       flags |= BA_UNMAPPED;
 
        for (error = 0; uio->uio_resid > 0;) {
                lbn = lblkno(fs, uio->uio_offset);
@@ -741,8 +749,13 @@ ffs_write(ap)
                if (size < xfersize)
                        xfersize = size;
 
-               error = vn_io_fault_uiomove((char *)bp->b_data + blkoffset,
-                   (int)xfersize, uio);
+               if ((bp->b_flags & B_UNMAPPED) == 0) {
+                       error = vn_io_fault_uiomove((char *)bp->b_data +
+                           blkoffset, (int)xfersize, uio);
+               } else {
+                       error = vn_io_fault_pgmove(bp->b_pages, blkoffset,
+                           (int)xfersize, uio);
+               }
                /*
                 * If the buffer is not already filled and we encounter an
                 * error while trying to fill it, we have to clear out any
@@ -786,7 +799,7 @@ ffs_write(ap)
                        if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) {
                                bp->b_flags |= B_CLUSTEROK;
                                cluster_write(vp, bp, ip->i_size, seqcount,
-                                   0);
+                                   GB_UNMAPPED);
                        } else {
                                bawrite(bp);
                        }

Modified: head/sys/ufs/ufs/ufs_extern.h
==============================================================================
--- head/sys/ufs/ufs/ufs_extern.h       Tue Mar 19 15:05:21 2013        
(r248520)
+++ head/sys/ufs/ufs/ufs_extern.h       Tue Mar 19 15:08:15 2013        
(r248521)
@@ -121,6 +121,7 @@ void        softdep_revert_rmdir(struct inode *
  */
 #define BA_CLRBUF      0x00010000      /* Clear invalid areas of buffer. */
 #define BA_METAONLY    0x00020000      /* Return indirect block buffer. */
+#define        BA_UNMAPPED     0x00040000      /* Do not mmap resulted buffer. 
*/
 #define BA_SEQMASK     0x7F000000      /* Bits holding seq heuristic. */
 #define BA_SEQSHIFT    24
 #define BA_SEQMAX      0x7F
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to