Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 May 2012 23:31:49 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r236209 - stable/9/sys/fs/tmpfs
Message-ID:  <201205282331.q4SNVnGA039930@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Mon May 28 23:31:48 2012
New Revision: 236209
URL: http://svn.freebsd.org/changeset/base/236209

Log:
  MFC r230120
    Neither tmpfs_nocacheread() nor tmpfs_mappedwrite() needs to call
    vm_object_pip_{add,subtract}() on the swap object because the swap
    object can't be destroyed while the vnode is exclusively locked.
    Moreover, even if the swap object could have been destroyed during
    tmpfs_nocacheread() and tmpfs_mappedwrite() this code is broken
    because vm_object_pip_subtract() does not wake up the sleeping thread
    that is trying to destroy the swap object.
  
    Free invalid pages after an I/O error.  There is no virtue in keeping
    them around in the swap object creating more work for the page daemon.
    (I believe that any non-busy page in the swap object will now always
    be valid.)
  
    vm_pager_get_pages() does not return a standard errno, so its return
    value should not be returned by tmpfs without translation to an errno
    value.
  
    There is no reason for the wakeup on vpg in tmpfs_mappedwrite() to
    occur with the swap object locked.
  
    Eliminate printf()s from tmpfs_nocacheread() and tmpfs_mappedwrite().
    (The swap pager already spams your console if data corruption is
    imminent.)

Modified:
  stable/9/sys/fs/tmpfs/tmpfs_subr.c
  stable/9/sys/fs/tmpfs/tmpfs_vnops.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/fs/   (props changed)

Modified: stable/9/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- stable/9/sys/fs/tmpfs/tmpfs_subr.c	Mon May 28 22:58:13 2012	(r236208)
+++ stable/9/sys/fs/tmpfs/tmpfs_subr.c	Mon May 28 23:31:48 2012	(r236209)
@@ -1002,6 +1002,7 @@ retry:
 					vm_page_sleep(m, "tmfssz");
 					goto retry;
 				}
+				MPASS(m->valid == VM_PAGE_BITS_ALL);
 			} else if (vm_pager_has_page(uobj, idx, NULL, NULL)) {
 				m = vm_page_alloc(uobj, idx, VM_ALLOC_NORMAL);
 				if (m == NULL) {
@@ -1034,7 +1035,6 @@ retry:
 			}
 			if (m != NULL) {
 				pmap_zero_page_area(m, base, PAGE_SIZE - base);
-				MPASS(m->valid == VM_PAGE_BITS_ALL);
 				vm_page_dirty(m);
 				vm_pager_page_unswapped(m);
 			}

Modified: stable/9/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- stable/9/sys/fs/tmpfs/tmpfs_vnops.c	Mon May 28 22:58:13 2012	(r236208)
+++ stable/9/sys/fs/tmpfs/tmpfs_vnops.c	Mon May 28 23:31:48 2012	(r236209)
@@ -445,18 +445,20 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p
     vm_offset_t offset, size_t tlen, struct uio *uio)
 {
 	vm_page_t	m;
-	int		error;
+	int		error, rv;
 
 	VM_OBJECT_LOCK(tobj);
-	vm_object_pip_add(tobj, 1);
 	m = vm_page_grab(tobj, idx, VM_ALLOC_WIRED |
 	    VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (m->valid != VM_PAGE_BITS_ALL) {
 		if (vm_pager_has_page(tobj, idx, NULL, NULL)) {
-			error = vm_pager_get_pages(tobj, &m, 1, 0);
-			if (error != 0) {
-				printf("tmpfs get pages from pager error [read]\n");
-				goto out;
+			rv = vm_pager_get_pages(tobj, &m, 1, 0);
+			if (rv != VM_PAGER_OK) {
+				vm_page_lock(m);
+				vm_page_free(m);
+				vm_page_unlock(m);
+				VM_OBJECT_UNLOCK(tobj);
+				return (EIO);
 			}
 		} else
 			vm_page_zero_invalid(m, TRUE);
@@ -464,12 +466,10 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p
 	VM_OBJECT_UNLOCK(tobj);
 	error = uiomove_fromphys(&m, offset, tlen, uio);
 	VM_OBJECT_LOCK(tobj);
-out:
 	vm_page_lock(m);
 	vm_page_unwire(m, TRUE);
 	vm_page_unlock(m);
 	vm_page_wakeup(m);
-	vm_object_pip_subtract(tobj, 1);
 	VM_OBJECT_UNLOCK(tobj);
 
 	return (error);
@@ -632,7 +632,7 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_o
 	vm_offset_t	offset;
 	off_t		addr;
 	size_t		tlen;
-	int		error;
+	int		error, rv;
 
 	error = 0;
 	
@@ -672,14 +672,16 @@ lookupvpg:
 	}
 nocache:
 	VM_OBJECT_LOCK(tobj);
-	vm_object_pip_add(tobj, 1);
 	tpg = vm_page_grab(tobj, idx, VM_ALLOC_WIRED |
 	    VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (tpg->valid != VM_PAGE_BITS_ALL) {
 		if (vm_pager_has_page(tobj, idx, NULL, NULL)) {
-			error = vm_pager_get_pages(tobj, &tpg, 1, 0);
-			if (error != 0) {
-				printf("tmpfs get pages from pager error [write]\n");
+			rv = vm_pager_get_pages(tobj, &tpg, 1, 0);
+			if (rv != VM_PAGER_OK) {
+				vm_page_lock(tpg);
+				vm_page_free(tpg);
+				vm_page_unlock(tpg);
+				error = EIO;
 				goto out;
 			}
 		} else
@@ -693,9 +695,6 @@ nocache:
 		pmap_copy_page(vpg, tpg);
 	}
 	VM_OBJECT_LOCK(tobj);
-out:
-	if (vobj != NULL)
-		VM_OBJECT_LOCK(vobj);
 	if (error == 0) {
 		KASSERT(tpg->valid == VM_PAGE_BITS_ALL,
 		    ("parts of tpg invalid"));
@@ -705,12 +704,13 @@ out:
 	vm_page_unwire(tpg, TRUE);
 	vm_page_unlock(tpg);
 	vm_page_wakeup(tpg);
-	if (vpg != NULL)
+out:
+	VM_OBJECT_UNLOCK(tobj);
+	if (vpg != NULL) {
+		VM_OBJECT_LOCK(vobj);
 		vm_page_wakeup(vpg);
-	if (vobj != NULL)
 		VM_OBJECT_UNLOCK(vobj);
-	vm_object_pip_subtract(tobj, 1);
-	VM_OBJECT_UNLOCK(tobj);
+	}
 
 	return	(error);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205282331.q4SNVnGA039930>