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 Track page dirtyn...



details:   https://anonhg.NetBSD.org/src/rev/5458c647bad6
branches:  trunk
changeset: 467258:5458c647bad6
user:      ad <ad%NetBSD.org@localhost>
date:      Sat Jan 18 15:21:32 2020 +0000

description:
Track page dirtyness for ZFS (yamt-pagecache).  I had forgotten that it had
its own cache.  Thanks to hannken@ for the repro.

diffstat:

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

diffs (54 lines):

diff -r 625b6aea8b99 -r 5458c647bad6 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c    Sat Jan 18 15:16:47 2020 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c    Sat Jan 18 15:21:32 2020 +0000
@@ -779,7 +779,7 @@
        struct uvm_object *uobj = &vp->v_uobj;
        kmutex_t *mtx = uobj->vmobjlock;
        caddr_t va;
-       int off;
+       int off, status;
 
        ASSERT(vp->v_mount != NULL);
 
@@ -796,6 +796,26 @@
                found = uvn_findpages(uobj, start, &npages, &pp, NULL,
                    UFP_NOALLOC);
                if (found) {
+                       /*
+                        * We're about to zap the page's contents and don't
+                        * care about any existing modifications.  We must
+                        * keep track of any new modifications past this
+                        * point.  Clear the modified bit in the pmap, and
+                        * if the page is marked dirty revert to tracking
+                        * the modified bit.
+                        */
+                       switch (uvm_pagegetdirty(pp)) {
+                       case UVM_PAGE_STATUS_DIRTY:
+                               /* Does pmap_clear_modify(). */
+                               uvm_pagemarkdirty(pp, UVM_PAGE_STATUS_UNKNOWN);
+                               break;
+                       case UVM_PAGE_STATUS_UNKNOWN:
+                               pmap_clear_modify(pp);
+                               break;
+                       case UVM_PAGE_STATUS_CLEAN:
+                               /* Nothing to do. */
+                               break;
+                       }
                        mutex_exit(mtx);
 
                        va = zfs_map_page(pp, S_WRITE);
@@ -5990,10 +6010,13 @@
 
                mutex_enter(mtx);
                pg->flags &= ~(PG_FAKE);
-               pmap_clear_modify(pg);
        }
 
        if (memwrite) {
+               if (uvm_pagegetdirty(pg) == UVM_PAGE_STATUS_CLEAN) {
+                       /* For write faults, start dirtiness tracking. */
+                       uvm_pagemarkdirty(pg, UVM_PAGE_STATUS_UNKNOWN);
+               }
                if ((vp->v_iflag & VI_ONWORKLST) == 0) {
                        vn_syncer_add_to_worklist(vp, filedelay);
                }



Home | Main Index | Thread Index | Old Index