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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to