summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-05-24 09:48:42 +0000
committerkib <kib@FreeBSD.org>2013-05-24 09:48:42 +0000
commit6023beb9dec8d71f3007154d4092db0eca926383 (patch)
tree23da013469d381d0c2b834ca81a889b4b40c3246 /sys/dev
parent10ab6671008c9ae3ac81b60ae8fde39d2aa133ad (diff)
downloadFreeBSD-src-6023beb9dec8d71f3007154d4092db0eca926383.zip
FreeBSD-src-6023beb9dec8d71f3007154d4092db0eca926383.tar.gz
Fix the data corruption on the swap-backed md.
Assign the rv variable a success code if the pager was not asked for the page. Using an error code from the previous processed page caused zeroing of the valid page, when e.g. the previous page was not available in the pager. Reported by: lstewart Sponsored by: The FreeBSD Foundation MFC after: 1 week
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/md/md.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index e871d8f..57c5b57 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -829,7 +829,9 @@ mdstart_swap(struct md_s *sc, struct bio *bp)
m = vm_page_grab(sc->object, i, VM_ALLOC_NORMAL |
VM_ALLOC_RETRY);
if (bp->bio_cmd == BIO_READ) {
- if (m->valid != VM_PAGE_BITS_ALL)
+ if (m->valid == VM_PAGE_BITS_ALL)
+ rv = VM_PAGER_OK;
+ else
rv = vm_pager_get_pages(sc->object, &m, 1, 0);
if (rv == VM_PAGER_ERROR) {
vm_page_wakeup(m);
@@ -854,6 +856,8 @@ mdstart_swap(struct md_s *sc, struct bio *bp)
} else if (bp->bio_cmd == BIO_WRITE) {
if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL)
rv = vm_pager_get_pages(sc->object, &m, 1, 0);
+ else
+ rv = VM_PAGER_OK;
if (rv == VM_PAGER_ERROR) {
vm_page_wakeup(m);
break;
@@ -868,6 +872,8 @@ mdstart_swap(struct md_s *sc, struct bio *bp)
} 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);
+ else
+ rv = VM_PAGER_OK;
if (rv == VM_PAGER_ERROR) {
vm_page_wakeup(m);
break;
OpenPOWER on IntegriCloud