diff options
author | kib <kib@FreeBSD.org> | 2011-01-27 16:10:25 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-01-27 16:10:25 +0000 |
commit | 83917be69e7e64451feec5423810f91357662399 (patch) | |
tree | a954dac4599546bce04d3776226bbf9912f7c4a8 /sys/dev/md/md.c | |
parent | e0953f64d353b5b62c4b32e89ba2914eb1fdec24 (diff) | |
download | FreeBSD-src-83917be69e7e64451feec5423810f91357662399.zip FreeBSD-src-83917be69e7e64451feec5423810f91357662399.tar.gz |
Add support for BIO_DELETE on swap-backed md(4). In the case of BIO_DELETE
covering the whole page, free the page. Otherwise, clear the region and
mark it clean. Not marking the page dirty could reinstantiate cleared
data, but it is allowed by BIO_DELETE specification and saves unneeded
write to swap.
Reviewed by: alc
Tested by: pho
MFC after: 2 weeks
Diffstat (limited to 'sys/dev/md/md.c')
-rw-r--r-- | sys/dev/md/md.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index c04f2a7..ee78dfe 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -649,7 +649,6 @@ mdstart_swap(struct md_s *sc, struct bio *bp) } bcopy(p, (void *)(sf_buf_kva(sf) + offs), len); m->valid = VM_PAGE_BITS_ALL; -#if 0 } else if (bp->bio_cmd == BIO_DELETE) { if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL) rv = vm_pager_get_pages(sc->object, &m, 1, 0); @@ -659,16 +658,21 @@ mdstart_swap(struct md_s *sc, struct bio *bp) vm_page_wakeup(m); break; } - bzero((void *)(sf_buf_kva(sf) + offs), len); - vm_page_dirty(m); - m->valid = VM_PAGE_BITS_ALL; -#endif + if (len != PAGE_SIZE) { + bzero((void *)(sf_buf_kva(sf) + offs), len); + vm_page_clear_dirty(m, offs, len); + m->valid = VM_PAGE_BITS_ALL; + } else + vm_pager_page_unswapped(m); } sf_buf_free(sf); sched_unpin(); vm_page_wakeup(m); vm_page_lock(m); - vm_page_activate(m); + if (bp->bio_cmd == BIO_DELETE && len == PAGE_SIZE) + vm_page_free(m); + else + vm_page_activate(m); vm_page_unlock(m); if (bp->bio_cmd == BIO_WRITE) vm_page_dirty(m); |