summaryrefslogtreecommitdiff
path: root/mach-defpager
diff options
context:
space:
mode:
authorMaksym Planeta <mcsim.planeta@gmail.com>2012-04-07 19:10:39 +0300
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-04-08 22:17:09 +0200
commit50aa82b6f21867bcad925a2879f8bd5c8773330b (patch)
tree2f7e7fb43bf5ae7515c0716711be08af20718e53 /mach-defpager
parent116fc73d851c49a40206e45e9af098669417f391 (diff)
Add appropriate checks to take into account that pager's memory map could be sparse.
* mach-defpager/default_pager.c (pager_truncate, pager_read_offset, pager_release_offset, pager_dealloc, pager_realloc): Add checks for map field being NULL. (pager_dealloc): Set map pointer to zero.
Diffstat (limited to 'mach-defpager')
-rw-r--r--mach-defpager/default_pager.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c
index 5d252443..e38dbb2b 100644
--- a/mach-defpager/default_pager.c
+++ b/mach-defpager/default_pager.c
@@ -1060,16 +1060,27 @@ pager_truncate(dpager_t pager, vm_size_t new_size) /* in pages */
vm_size_t old_size, vm_size_t new_size)
{
vm_size_t i;
+
+ if (!mapptr)
+ return;
+
for (i = new_size; i < old_size; ++i)
{
const union dp_map entry = mapptr[i];
- pager_dealloc_page(entry.block.p_index, entry.block.p_offset,
- TRUE);
- invalidate_block(mapptr[i]);
+ if (!no_block(entry))
+ {
+ pager_dealloc_page(entry.block.p_index, entry.block.p_offset,
+ TRUE);
+ invalidate_block(mapptr[i]);
+ }
}
}
mutex_lock(&pager->lock); /* XXX lock_write */
+
+ if (!pager->map)
+ goto done;
+
old_size = pager->size;
if (INDIRECT_PAGEMAP(old_size))
@@ -1134,6 +1145,7 @@ pager_truncate(dpager_t pager, vm_size_t new_size) /* in pages */
}
}
+ done:
pager->size = new_size;
mutex_unlock(&pager->lock);
@@ -1178,17 +1190,19 @@ pager_read_offset(pager, offset)
#endif
}
+ invalidate_block(pager_offset);
if (INDIRECT_PAGEMAP(pager->size)) {
register dp_map_t mapptr;
- mapptr = pager->map[f_page/PAGEMAP_ENTRIES].indirect;
- if (mapptr == 0)
- invalidate_block(pager_offset);
- else
- pager_offset = mapptr[f_page%PAGEMAP_ENTRIES];
+ if (pager->map) {
+ mapptr = pager->map[f_page/PAGEMAP_ENTRIES].indirect;
+ if (mapptr)
+ pager_offset = mapptr[f_page%PAGEMAP_ENTRIES];
+ }
}
else {
- pager_offset = pager->map[f_page];
+ if (pager->map)
+ pager_offset = pager->map[f_page];
}
#if DEBUG_READER_CONFLICTS
@@ -1212,6 +1226,7 @@ void pager_release_offset(pager, offset)
mutex_lock(&pager->lock); /* XXX lock_read */
+ assert (pager->map);
if (INDIRECT_PAGEMAP(pager->size)) {
register dp_map_t mapptr;
@@ -1568,6 +1583,9 @@ pager_dealloc(pager)
register dp_map_t mapptr;
register union dp_map block;
+ if (!pager->map)
+ return;
+
if (INDIRECT_PAGEMAP(pager->size)) {
for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
mapptr = pager->map[i].indirect;
@@ -1579,9 +1597,11 @@ pager_dealloc(pager)
block.block.p_offset, TRUE);
}
kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
+ pager->map[i].indirect = (dp_map_t) 0;
}
}
kfree((char *)pager->map, INDIRECT_PAGEMAP_SIZE(pager->size));
+ pager->map = (dp_map_t) 0;
#ifdef CHECKSUM
for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
mapptr = (vm_offset_t *)pager->checksum[i];
@@ -1602,6 +1622,7 @@ pager_dealloc(pager)
block.block.p_offset, TRUE);
}
kfree((char *)pager->map, PAGEMAP_SIZE(pager->size));
+ pager->map = (dp_map_t) 0;
#ifdef CHECKSUM
kfree((char *)pager->checksum, PAGEMAP_SIZE(pager->size));
#endif /* CHECKSUM */
@@ -1624,6 +1645,9 @@ pager_realloc(pager, pindex)
vm_size_t size;
union dp_map block;
+ if (!pager->map)
+ return TRUE;
+
size = pager->size; /* in pages */
map = pager->map;