svn commit: r250966 - head/sys/dev/md
Konstantin Belousov
kib at FreeBSD.org
Fri May 24 09:48:43 UTC 2013
Author: kib
Date: Fri May 24 09:48:42 2013
New Revision: 250966
URL: http://svnweb.freebsd.org/changeset/base/250966
Log:
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
Modified:
head/sys/dev/md/md.c
Modified: head/sys/dev/md/md.c
==============================================================================
--- head/sys/dev/md/md.c Fri May 24 09:33:55 2013 (r250965)
+++ head/sys/dev/md/md.c Fri May 24 09:48:42 2013 (r250966)
@@ -829,7 +829,9 @@ mdstart_swap(struct md_s *sc, struct bio
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
} 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
} 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;
More information about the svn-src-all
mailing list