Author: avg
Date: Wed Jul 13 09:09:34 2016
New Revision: 302722
URL: https://svnweb.freebsd.org/changeset/base/302722

Log:
  MFC r298105: zfs: enable vn_io_fault support

Modified:
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c       Wed Jul 
13 09:09:21 2016        (r302721)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c       Wed Jul 
13 09:09:34 2016        (r302722)
@@ -1025,8 +1025,13 @@ dmu_read_uio(objset_t *os, uint64_t obje
                        else
                                XUIOSTAT_BUMP(xuiostat_rbuf_copied);
                } else {
+#ifdef illumos
                        err = uiomove((char *)db->db_data + bufoff, tocpy,
                            UIO_READ, uio);
+#else
+                       err = vn_io_fault_uiomove((char *)db->db_data + bufoff,
+                           tocpy, uio);
+#endif
                }
                if (err)
                        break;
@@ -1068,6 +1073,7 @@ dmu_write_uio_dnode(dnode_t *dn, uio_t *
                else
                        dmu_buf_will_dirty(db, tx);
 
+#ifdef illumos
                /*
                 * XXX uiomove could block forever (eg. nfs-backed
                 * pages).  There needs to be a uiolockdown() function
@@ -1076,6 +1082,10 @@ dmu_write_uio_dnode(dnode_t *dn, uio_t *
                 */
                err = uiomove((char *)db->db_data + bufoff, tocpy,
                    UIO_WRITE, uio);
+#else
+               err = vn_io_fault_uiomove((char *)db->db_data + bufoff, tocpy,
+                   uio);
+#endif
 
                if (tocpy == db->db_size)
                        dmu_buf_fill_done(db, tx);

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c        
Wed Jul 13 09:09:21 2016        (r302721)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c        
Wed Jul 13 09:09:34 2016        (r302722)
@@ -1182,6 +1182,7 @@ zfs_domount(vfs_t *vfsp, char *osname)
        vfsp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
        vfsp->mnt_kern_flag |= MNTK_SHARED_WRITES;
        vfsp->mnt_kern_flag |= MNTK_EXTENDED_SHARED;
+       vfsp->mnt_kern_flag |= MNTK_NO_IOPF;    /* vn_io_fault can be used */
 
        /*
         * The fsid is 64 bits, composed of an 8-bit fs type, which

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Jul 
13 09:09:21 2016        (r302721)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Jul 
13 09:09:34 2016        (r302722)
@@ -595,7 +595,11 @@ mappedread(vnode_t *vp, int nbytes, uio_
 
                        VM_OBJECT_UNLOCK(obj);
                        va = zfs_map_page(pp, &sf);
+#ifdef illumos
                        error = uiomove(va + off, bytes, UIO_READ, uio);
+#else
+                       error = vn_io_fault_uiomove(va + off, bytes, uio);
+#endif
                        zfs_unmap_page(sf);
                        VM_OBJECT_LOCK(obj);
                        page_unhold(pp);
@@ -962,18 +966,31 @@ zfs_write(vnode_t *vp, uio_t *uio, int i
                         * holding up the transaction if the data copy hangs
                         * up on a pagefault (e.g., from an NFS server mapping).
                         */
+#ifdef illumos
                        size_t cbytes;
+#endif
 
                        abuf = dmu_request_arcbuf(sa_get_db(zp->z_sa_hdl),
                            max_blksz);
                        ASSERT(abuf != NULL);
                        ASSERT(arc_buf_size(abuf) == max_blksz);
+#ifdef illumos
                        if (error = uiocopy(abuf->b_data, max_blksz,
                            UIO_WRITE, uio, &cbytes)) {
                                dmu_return_arcbuf(abuf);
                                break;
                        }
                        ASSERT(cbytes == max_blksz);
+#else
+                       ssize_t resid = uio->uio_resid;
+                       error = vn_io_fault_uiomove(abuf->b_data, max_blksz, 
uio);
+                       if (error != 0) {
+                               uio->uio_offset -= resid - uio->uio_resid;
+                               uio->uio_resid = resid;
+                               dmu_return_arcbuf(abuf);
+                               break;
+                       }
+#endif
                }
 
                /*
@@ -1045,8 +1062,10 @@ zfs_write(vnode_t *vp, uio_t *uio, int i
                                dmu_assign_arcbuf(sa_get_db(zp->z_sa_hdl),
                                    woff, abuf, tx);
                        }
+#ifdef illumos
                        ASSERT(tx_bytes <= uio->uio_resid);
                        uioskip(uio, tx_bytes);
+#endif
                }
                if (tx_bytes && vn_has_cached_data(vp)) {
                        update_pages(vp, woff, tx_bytes, zfsvfs->z_os,
@@ -1100,7 +1119,11 @@ zfs_write(vnode_t *vp, uio_t *uio, int i
                while ((end_size = zp->z_size) < uio->uio_loffset) {
                        (void) atomic_cas_64(&zp->z_size, end_size,
                            uio->uio_loffset);
+#ifdef illumos
                        ASSERT(error == 0);
+#else
+                       ASSERT(error == 0 || error == EFAULT);
+#endif
                }
                /*
                 * If we are replaying and eof is non zero then force
@@ -1110,7 +1133,10 @@ zfs_write(vnode_t *vp, uio_t *uio, int i
                if (zfsvfs->z_replay && zfsvfs->z_replay_eof != 0)
                        zp->z_size = zfsvfs->z_replay_eof;
 
-               error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+               if (error == 0)
+                       error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
+               else
+                       (void) sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
 
                zfs_log_write(zilog, tx, TX_WRITE, zp, woff, tx_bytes, ioflag);
                dmu_tx_commit(tx);
@@ -1137,6 +1163,17 @@ zfs_write(vnode_t *vp, uio_t *uio, int i
                return (error);
        }
 
+#ifdef __FreeBSD__
+       /*
+        * EFAULT means that at least one page of the source buffer was not
+        * available.  VFS will re-try remaining I/O upon this error.
+        */
+       if (error == EFAULT) {
+               ZFS_EXIT(zfsvfs);
+               return (error);
+       }
+#endif
+
        if (ioflag & (FSYNC | FDSYNC) ||
            zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
                zil_commit(zilog, zp->z_id);
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to