Module Name: src
Committed By: ad
Date: Wed May 20 20:47:18 UTC 2020
Modified Files:
src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_vnops.c
Log Message:
zfs_netbsd_getpages:
- implement the PGO_LOCKED case
- handle npages > 1 for PGO_SYNCIO
To generate a diff of this commit:
cvs rdiff -u -r1.67 -r1.68 \
src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.67 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.68
--- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.67 Sat May 16 18:31:46 2020
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Wed May 20 20:47:18 2020
@@ -755,15 +755,14 @@ mappedread(vnode_t *vp, int nbytes, uio_
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 @@ zfs_netbsd_getpages(void *v)
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 @@ zfs_netbsd_getpages(void *v)
fstrans_done(mp);
return EINVAL;
}
- npages = 1;
- pg = NULL;
- uvn_findpages(uobj, offset, &npages, &pg, NULL, UFP_ALL);
+ npages = *ap->a_count;
+ uvn_findpages(uobj, offset, &npages, ap->a_m, NULL, UFP_ALL);
- if (pg->flags & PG_FAKE) {
- rw_exit(rw);
+ 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);
+ 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);
- }
+ 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);
+ 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);