kernel/file_cache: Re-check the cache size after acquiring the lock.
If it changed, then don't try to do I/O past the end. It would presumably just fail anyway, and since the addition of extra asserts to VMCache page insertion, will cause assertion failures due to inserting pages past the end of the cache. This case is particularly easy to trigger by holding the down arrow in the keymaps list (i.e. changing keymaps very rapidly.)
This commit is contained in:
+21
-9
@@ -750,21 +750,33 @@ cache_io(void* _cacheRef, void* cookie, off_t offset, addr_t buffer,
|
||||
// satisfied request part
|
||||
|
||||
const uint32 kMaxChunkSize = MAX_IO_VECS * B_PAGE_SIZE;
|
||||
size_t bytesLeft = size, lastLeft = size;
|
||||
int32 lastPageOffset = pageOffset;
|
||||
addr_t lastBuffer = buffer;
|
||||
off_t lastOffset = offset;
|
||||
size_t lastReservedPages = min_c(MAX_IO_VECS, (pageOffset + bytesLeft
|
||||
+ B_PAGE_SIZE - 1) >> PAGE_SHIFT);
|
||||
size_t reservePages = 0;
|
||||
size_t pagesProcessed = 0;
|
||||
cache_func function = NULL;
|
||||
|
||||
size_t lastReservedPages = min_c(MAX_IO_VECS, (pageOffset + size
|
||||
+ B_PAGE_SIZE - 1) >> PAGE_SHIFT);
|
||||
vm_page_reservation reservation;
|
||||
reserve_pages(ref, &reservation, lastReservedPages, doWrite);
|
||||
|
||||
AutoLocker<VMCache> locker(cache);
|
||||
|
||||
// Now that we have the lock, make sure the situation didn't change.
|
||||
if ((pageOffset + offset) >= cache->virtual_end) {
|
||||
locker.Unlock();
|
||||
vm_page_unreserve_pages(&reservation);
|
||||
|
||||
*_size = 0;
|
||||
return B_OK;
|
||||
}
|
||||
if ((off_t)(pageOffset + offset + size) > cache->virtual_end)
|
||||
size = cache->virtual_end - (pageOffset + offset);
|
||||
|
||||
size_t bytesLeft = size, lastLeft = size;
|
||||
int32 lastPageOffset = pageOffset;
|
||||
addr_t lastBuffer = buffer;
|
||||
off_t lastOffset = offset;
|
||||
size_t reservePages = 0;
|
||||
size_t pagesProcessed = 0;
|
||||
cache_func function = NULL;
|
||||
|
||||
while (bytesLeft > 0) {
|
||||
// Periodically reevaluate the low memory situation and select the
|
||||
// read/write hook accordingly
|
||||
|
||||
Reference in New Issue
Block a user