Ticket #8889: 0001-Handle-discarded-blocks-in-unflushed-transaction.patch

File 0001-Handle-discarded-blocks-in-unflushed-transaction.patch, 1.8 KB (added by ahenriksson, 12 years ago)
  • src/system/kernel/cache/block_cache.cpp

    From 1686cffde898b88dcabbf6ecaa46b81196b42bab Mon Sep 17 00:00:00 2001
    From: ahenriksson <sausageboy@gmail.com>
    Date: Wed, 15 Aug 2012 19:04:36 +0200
    Subject: [PATCH] Handle discarded blocks in unflushed transaction
    
    If a block had been discarded, but was still in an unflushed
    transaction, old cached data would be read instead of the data on the
    disk.
    ---
     src/system/kernel/cache/block_cache.cpp | 32 ++++++++++++++++++++++++++++++++
     1 fil ändrad, 32 tillägg(+)
    
    diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp
    index 943e651..a66afc6 100644
    a b retry:  
    18401840        // The block is currently busy_reading - wait and try again later
    18411841        wait_for_busy_reading_block(cache, block);
    18421842        goto retry;
     1843    } else if (block->discard) {
     1844        // The block has been discarded, but the transaction is not yet
     1845        // flushed. We remove the block from the transaction and discard
     1846        // it ourselves.
     1847
     1848        ASSERT(block->transaction != NULL);
     1849
     1850        // Search through the singly linked transaction list, and remove the
     1851        // block once we find it
     1852        // TODO: This is slow, but it should be an uncommon operation anyways
     1853        cached_block** previousLink = &block->transaction->first_block;
     1854        cached_block* current = block->transaction->first_block;
     1855
     1856        while (true) {
     1857            if (current == block) {
     1858                // remove the block from its transaction
     1859                *previousLink = block->transaction_next;
     1860                block->transaction->num_blocks--;
     1861                break;
     1862            }
     1863
     1864            previousLink = &current->transaction_next;
     1865            current = current->transaction_next;
     1866
     1867            if (current == NULL) {
     1868                panic("Discarded block was not in its transaction!");
     1869                return NULL;
     1870            }
     1871        }
     1872       
     1873        cache->DiscardBlock(block);
     1874        goto retry;
    18431875    }
    18441876
    18451877    if (block->unused) {