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