svn commit: r248946 - stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Andriy Gapon
avg at FreeBSD.org
Sun Mar 31 13:56:14 UTC 2013
Author: avg
Date: Sun Mar 31 13:56:13 2013
New Revision: 248946
URL: http://svnweb.freebsd.org/changeset/base/248946
Log:
MFC r246293: zfs: fix, improve and re-organize page_lookup and page_unlock
Please note that because of the significant VM API differences between HEAD
and stable/8 this commit has some additional changes.
Modified:
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/cddl/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sun Mar 31 13:54:44 2013 (r248945)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sun Mar 31 13:56:13 2013 (r248946)
@@ -323,7 +323,7 @@ zfs_ioctl(vnode_t *vp, u_long com, intpt
}
static vm_page_t
-page_lookup(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes)
+page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes)
{
vm_object_t obj;
vm_page_t pp;
@@ -333,19 +333,23 @@ page_lookup(vnode_t *vp, int64_t start,
for (;;) {
if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL &&
- vm_page_is_valid(pp, (vm_offset_t)off, nbytes)) {
+ pp->valid) {
if (vm_page_sleep_if_busy(pp, FALSE, "zfsmwb"))
continue;
- vm_page_busy(pp);
+ } else {
+ pp = vm_page_alloc(obj, OFF_TO_IDX(start),
+ VM_ALLOC_SYSTEM | VM_ALLOC_IFCACHED |
+ VM_ALLOC_NOBUSY);
+ }
+
+ if (pp != NULL) {
+ ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL);
+ vm_object_pip_add(obj, 1);
+ vm_page_io_start(pp);
vm_page_lock_queues();
- vm_page_undirty(pp);
+ pmap_remove_write(pp);
+ vm_page_clear_dirty(pp, off, nbytes);
vm_page_unlock_queues();
- } else {
- if (__predict_false(obj->cache != NULL)) {
- vm_page_cache_free(obj, OFF_TO_IDX(start),
- OFF_TO_IDX(start) + 1);
- }
- pp = NULL;
}
break;
}
@@ -353,10 +357,46 @@ page_lookup(vnode_t *vp, int64_t start,
}
static void
-page_unlock(vm_page_t pp)
+page_unbusy(vm_page_t pp)
{
- vm_page_wakeup(pp);
+ vm_page_io_finish(pp);
+ vm_object_pip_subtract(pp->object, 1);
+}
+
+static vm_page_t
+page_hold(vnode_t *vp, int64_t start)
+{
+ vm_object_t obj;
+ vm_page_t pp;
+
+ obj = vp->v_object;
+ VM_OBJECT_LOCK_ASSERT(obj, MA_OWNED);
+
+ for (;;) {
+ if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL &&
+ pp->valid) {
+ if (vm_page_sleep_if_busy(pp, FALSE, "zfsmwb"))
+ continue;
+ ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL);
+ vm_page_lock_queues();
+ vm_page_hold(pp);
+ vm_page_unlock_queues();
+
+ } else
+ pp = NULL;
+ break;
+ }
+ return (pp);
+}
+
+static void
+page_unhold(vm_page_t pp)
+{
+
+ vm_page_lock_queues();
+ vm_page_unhold(pp);
+ vm_page_unlock_queues();
}
static caddr_t
@@ -387,6 +427,7 @@ update_pages(vnode_t *vp, int64_t start,
{
vm_object_t obj;
struct sf_buf *sf;
+ caddr_t va;
int off;
ASSERT(vp->v_mount != NULL);
@@ -397,27 +438,44 @@ update_pages(vnode_t *vp, int64_t start,
VM_OBJECT_LOCK(obj);
for (start &= PAGEMASK; len > 0; start += PAGESIZE) {
vm_page_t pp;
- int nbytes = MIN(PAGESIZE - off, len);
+ int nbytes = imin(PAGESIZE - off, len);
- if ((pp = page_lookup(vp, start, off, nbytes)) != NULL) {
- caddr_t va;
+ if (segflg == UIO_NOCOPY) {
+ pp = vm_page_lookup(obj, OFF_TO_IDX(start));
+ KASSERT(pp != NULL,
+ ("zfs update_pages: NULL page in putpages case"));
+ KASSERT(off == 0,
+ ("zfs update_pages: unaligned data in putpages case"));
+ KASSERT(pp->valid == VM_PAGE_BITS_ALL,
+ ("zfs update_pages: invalid page in putpages case"));
+ KASSERT(pp->busy > 0,
+ ("zfs update_pages: unbusy page in putpages case"));
+ KASSERT(!pmap_page_is_write_mapped(pp),
+ ("zfs update_pages: writable page in putpages case"));
+ VM_OBJECT_UNLOCK(obj);
+
+ va = zfs_map_page(pp, &sf);
+ (void) dmu_write(os, oid, start, nbytes, va, tx);
+ zfs_unmap_page(sf);
+ VM_OBJECT_LOCK(obj);
+ vm_page_undirty(pp);
+ } else if ((pp = page_busy(vp, start, off, nbytes)) != NULL) {
VM_OBJECT_UNLOCK(obj);
+
va = zfs_map_page(pp, &sf);
- if (segflg == UIO_NOCOPY) {
- (void) dmu_write(os, oid, start+off, nbytes,
- va+off, tx);
- } else {
- (void) dmu_read(os, oid, start+off, nbytes,
- va+off, DMU_READ_PREFETCH);
- }
+ (void) dmu_read(os, oid, start+off, nbytes,
+ va+off, DMU_READ_PREFETCH);;
zfs_unmap_page(sf);
+
VM_OBJECT_LOCK(obj);
- page_unlock(pp);
+ page_unbusy(pp);
}
len -= nbytes;
off = 0;
}
+ if (segflg != UIO_NOCOPY)
+ vm_object_pip_wakeupn(obj, 0);
VM_OBJECT_UNLOCK(obj);
}
@@ -532,7 +590,7 @@ mappedread(vnode_t *vp, int nbytes, uio_
vm_page_t pp;
uint64_t bytes = MIN(PAGESIZE - off, len);
- if (pp = page_lookup(vp, start, off, bytes)) {
+ if (pp = page_hold(vp, start)) {
struct sf_buf *sf;
caddr_t va;
VM_OBJECT_UNLOCK(obj);
@@ -540,7 +598,7 @@ mappedread(vnode_t *vp, int nbytes, uio_
error = uiomove(va + off, bytes, UIO_READ, uio);
zfs_unmap_page(sf);
VM_OBJECT_LOCK(obj);
- page_unlock(pp);
+ page_unhold(pp);
} else {
VM_OBJECT_UNLOCK(obj);
error = dmu_read_uio(os, zp->z_id, uio, bytes);
More information about the svn-src-stable
mailing list