Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/cddl/osnet/dist/uts/common/fs/zfs zfs_netbsd_getpages:



details:   https://anonhg.NetBSD.org/src/rev/0e9a00b62344
branches:  trunk
changeset: 933175:0e9a00b62344
user:      ad <ad%NetBSD.org@localhost>
date:      Wed May 20 20:47:18 2020 +0000

description:
zfs_netbsd_getpages:

- implement the PGO_LOCKED case
- handle npages > 1 for PGO_SYNCIO

diffstat:

 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c |  82 ++++++++++++-----
 1 files changed, 55 insertions(+), 27 deletions(-)

diffs (113 lines):

diff -r 6539a9d68bce -r 0e9a00b62344 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c    Wed May 20 20:19:02 2020 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c    Wed May 20 20:47:18 2020 +0000
@@ -755,15 +755,14 @@
                        va = zfs_map_page(pp, S_READ);
                        error = uiomove(va + off, bytes, UIO_READ, uio);
                        zfs_unmap_page(pp, va);
+                       rw_enter(rw, RW_WRITER);
+                       uvm_page_unbusy(&pp, 1);
+                       rw_exit(rw);
                } else {
                        error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
                            uio, bytes);
                }
 
-               rw_enter(rw, RW_WRITER);
-               uvm_page_unbusy(&pp, 1);
-               rw_exit(rw);
-
                len -= bytes;
                off = 0;
                if (error)
@@ -5987,9 +5986,24 @@
        int npages, found, err = 0;
 
        if (flags & PGO_LOCKED) {
-               *ap->a_count = 0;
-               ap->a_m[ap->a_centeridx] = NULL;
-               return EBUSY;
+               uvn_findpages(uobj, ap->a_offset, ap->a_count, ap->a_m, NULL,
+                   UFP_NOWAIT | UFP_NOALLOC | UFP_NOBUSY |
+                   (memwrite ? UFP_NORDONLY : 0));
+               if (memwrite) {
+                       KASSERT(rw_write_held(uobj->vmobjlock));
+                       for (int i = 0; i < npages; i++) {
+                               pg = ap->a_m[i];
+                               if (pg == NULL || pg == PGO_DONTCARE) {
+                                       continue;
+                               }
+                               if (uvm_pagegetdirty(pg) ==
+                                   UVM_PAGE_STATUS_CLEAN) {
+                                       uvm_pagemarkdirty(pg,
+                                           UVM_PAGE_STATUS_UNKNOWN);
+                               }
+                       }
+               }
+               return ap->a_m[ap->a_centeridx] == NULL ? EBUSY : 0;
        }
        rw_exit(rw);
 
@@ -6016,28 +6030,42 @@
                fstrans_done(mp);
                return EINVAL;
        }
-       npages = 1;
-       pg = NULL;
-       uvn_findpages(uobj, offset, &npages, &pg, NULL, UFP_ALL);
-
-       if (pg->flags & PG_FAKE) {
-               rw_exit(rw);
-
-               va = zfs_map_page(pg, S_WRITE);
-               err = dmu_read(zfsvfs->z_os, zp->z_id, offset, PAGE_SIZE,
-                   va, DMU_READ_PREFETCH);
-               zfs_unmap_page(pg, va);
-
-               rw_enter(rw, RW_WRITER);
-               pg->flags &= ~(PG_FAKE);
-       }
-
-       if (memwrite && uvm_pagegetdirty(pg) == UVM_PAGE_STATUS_CLEAN) {
-               /* For write faults, start dirtiness tracking. */
-               uvm_pagemarkdirty(pg, UVM_PAGE_STATUS_UNKNOWN);
+       npages = *ap->a_count;
+       uvn_findpages(uobj, offset, &npages, ap->a_m, NULL, UFP_ALL);
+
+       for (int i = 0; i < npages; i++) {
+               pg = ap->a_m[i];
+               if (pg->flags & PG_FAKE) {
+                       rw_exit(rw);
+
+                       va = zfs_map_page(pg, S_WRITE);
+                       err = dmu_read(zfsvfs->z_os, zp->z_id, offset,
+                           PAGE_SIZE, va, DMU_READ_PREFETCH);
+                       zfs_unmap_page(pg, va);
+
+                       rw_enter(rw, RW_WRITER);
+                       if (err != 0) {
+                               for (i = 0; i < npages; i++) {
+                                       pg = ap->a_m[i];
+                                       if ((pg->flags & PG_FAKE) != 0) {
+                                               uvm_pagefree(pg);
+                                       } else {
+                                               uvm_page_unbusy(&pg, 1);
+                                       }
+                               }
+                               memset(ap->a_m, 0, sizeof(ap->a_m[0]) *
+                                   npages);
+                               break;
+                       }
+                       pg->flags &= ~(PG_FAKE);
+               }
+
+               if (memwrite && uvm_pagegetdirty(pg) == UVM_PAGE_STATUS_CLEAN) {
+                       /* For write faults, start dirtiness tracking. */
+                       uvm_pagemarkdirty(pg, UVM_PAGE_STATUS_UNKNOWN);
+               }
        }
        rw_exit(rw);
-       ap->a_m[ap->a_centeridx] = pg;
 
        ZFS_EXIT(zfsvfs);
        fstrans_done(mp);



Home | Main Index | Thread Index | Old Index