diff options
author | dillon <dillon@FreeBSD.org> | 1999-02-15 02:03:40 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1999-02-15 02:03:40 +0000 |
commit | 0a57647424617468a9b853152f0e07dd34904187 (patch) | |
tree | 45155ffa19e2ce6883d23e0ebb288f1699504d1d /sys/vm/vm_object.c | |
parent | c7d9cbf5597928705c5157952548381d222d0df5 (diff) | |
download | FreeBSD-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/vm/vm_object.c')
-rw-r--r-- | sys/vm/vm_object.c | 36 |
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); } } } |