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