summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>1999-02-15 02:03:40 +0000
committerdillon <dillon@FreeBSD.org>1999-02-15 02:03:40 +0000
commit0a57647424617468a9b853152f0e07dd34904187 (patch)
tree45155ffa19e2ce6883d23e0ebb288f1699504d1d /sys
parentc7d9cbf5597928705c5157952548381d222d0df5 (diff)
downloadFreeBSD-src-0a57647424617468a9b853152f0e07dd34904187.zip
FreeBSD-src-0a57647424617468a9b853152f0e07dd34904187.tar.gz
Fix a bug in the new madvise() code that would possibly (improperly)
free swap space out from under a busy page. This is not legal because the swap may be reallocated and I/O issued while I/O is still in progress on the same swap page from the madvise()'d object. This bug could only occur under extreme paging conditions but might not cause an error until much later. As a side-benefit, madvise() is now even smaller.
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vm_object.c36
1 files changed, 12 insertions, 24 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index cf4e6b1..686cf35 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.149 1999/02/12 09:51:43 dillon Exp $
+ * $Id: vm_object.c,v 1.150 1999/02/12 20:42:19 dillon Exp $
*/
/*
@@ -762,29 +762,6 @@ vm_object_madvise(object, pindex, count, advise)
end = pindex + count;
/*
- * MADV_FREE special case - free any swap backing store now,
- * whether or not resident pages can be found later.
- */
-
- if (advise == MADV_FREE) {
- tobject = object;
- tpindex = pindex;
-
- while (
- (tobject->type == OBJT_DEFAULT ||
- tobject->type == OBJT_SWAP) &&
- (tobject->flags & OBJ_ONEMAPPING)
- ) {
- if (tobject->type == OBJT_SWAP) {
- swap_pager_freespace(tobject, tpindex, count);
- }
- if ((tobject = tobject->backing_object) == NULL)
- break;
- tpindex += OFF_TO_IDX(tobject->backing_object_offset);
- }
- }
-
- /*
* Locate and adjust resident pages
*/
@@ -806,6 +783,15 @@ shadowlookup:
m = vm_page_lookup(tobject, tpindex);
if (m == NULL) {
+ /*
+ * There may be swap even if there is no backing page
+ */
+ if (advise == MADV_FREE && tobject->type == OBJT_SWAP)
+ swap_pager_freespace(tobject, tpindex, 1);
+
+ /*
+ * next object
+ */
tobject = tobject->backing_object;
if (tobject == NULL)
continue;
@@ -853,6 +839,8 @@ shadowlookup:
m->dirty = 0;
m->act_count = 0;
vm_page_deactivate(m);
+ if (tobject->type == OBJT_SWAP)
+ swap_pager_freespace(tobject, tpindex, 1);
}
}
}
OpenPOWER on IntegriCloud