Author: kib
Date: Fri Mar 15 11:16:12 2013
New Revision: 248319
URL: http://svnweb.freebsd.org/changeset/base/248319

Log:
  Implement the helper function vn_io_fault_pgmove(), intended to use by
  the filesystem VOP_READ() and VOP_WRITE() implementations in the same
  way as vn_io_fault_uiomove() over the unmapped buffers.  Helper
  provides the convenient wrapper over the pmap_copy_pages() for struct
  uio consumers, taking care of the TDP_UIOHELD situations.
  
  Sponsored by: The FreeBSD Foundation
  Tested by:    pho
  MFC after:    2 weeks

Modified:
  head/sys/kern/vfs_vnops.c
  head/sys/sys/vnode.h

Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c   Fri Mar 15 10:21:18 2013        (r248318)
+++ head/sys/kern/vfs_vnops.c   Fri Mar 15 11:16:12 2013        (r248319)
@@ -1122,6 +1122,45 @@ vn_io_fault_uiomove(char *data, int xfer
        return (error);
 }
 
+int
+vn_io_fault_pgmove(vm_page_t ma[], vm_offset_t offset, int xfersize,
+    struct uio *uio)
+{
+       struct thread *td;
+       vm_offset_t iov_base;
+       int cnt, pgadv;
+
+       td = curthread;
+       if ((td->td_pflags & TDP_UIOHELD) == 0 ||
+           uio->uio_segflg != UIO_USERSPACE)
+               return (uiomove_fromphys(ma, offset, xfersize, uio));
+
+       KASSERT(uio->uio_iovcnt == 1, ("uio_iovcnt %d", uio->uio_iovcnt));
+       cnt = xfersize > uio->uio_resid ? uio->uio_resid : xfersize;
+       iov_base = (vm_offset_t)uio->uio_iov->iov_base;
+       switch (uio->uio_rw) {
+       case UIO_WRITE:
+               pmap_copy_pages(td->td_ma, iov_base & PAGE_MASK, ma,
+                   offset, cnt);
+               break;
+       case UIO_READ:
+               pmap_copy_pages(ma, offset, td->td_ma, iov_base & PAGE_MASK,
+                   cnt);
+               break;
+       }
+       pgadv = ((iov_base + cnt) >> PAGE_SHIFT) - (iov_base >> PAGE_SHIFT);
+       td->td_ma += pgadv;
+       KASSERT(td->td_ma_cnt >= pgadv, ("consumed pages %d %d", td->td_ma_cnt,
+           pgadv));
+       td->td_ma_cnt -= pgadv;
+       uio->uio_iov->iov_base = (char *)(iov_base + cnt);
+       uio->uio_iov->iov_len -= cnt;
+       uio->uio_resid -= cnt;
+       uio->uio_offset += cnt;
+       return (0);
+}
+
+
 /*
  * File table truncate routine.
  */

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Fri Mar 15 10:21:18 2013        (r248318)
+++ head/sys/sys/vnode.h        Fri Mar 15 11:16:12 2013        (r248319)
@@ -693,6 +693,8 @@ int vn_vget_ino(struct vnode *vp, ino_t 
            struct vnode **rvp);
 
 int    vn_io_fault_uiomove(char *data, int xfersize, struct uio *uio);
+int    vn_io_fault_pgmove(vm_page_t ma[], vm_offset_t offset, int xfersize,
+           struct uio *uio);
 
 #define        vn_rangelock_unlock(vp, cookie)                                 
\
        rangelock_unlock(&(vp)->v_rl, (cookie), VI_MTX(vp))
_______________________________________________
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