Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.421
diff -u -p -r1.421 block.module
--- modules/block/block.module	13 May 2010 07:53:02 -0000	1.421
+++ modules/block/block.module	24 May 2010 02:49:09 -0000
@@ -356,6 +356,11 @@ function _block_rehash($theme = NULL) {
   foreach ($database_blocks as $block) {
     // Preserve info which is not in the database.
     $block->info = $current_blocks[$block->module][$block->delta]['info'];
+    // The cache mode can only by set from hook_block_info(), so that has
+    // precedence over the database's value.
+    if (isset($current_blocks[$block->module][$block->delta]['cache'])) {
+      $block->cache = $current_blocks[$block->module][$block->delta]['cache'];
+    }
     // Blocks stored in the database override the blocks defined in code.
     $current_blocks[$block->module][$block->delta] = get_object_vars($block);
     // Preserve this block.
@@ -386,7 +391,7 @@ function _block_rehash($theme = NULL) {
         $block['region'] = BLOCK_REGION_NONE;
       }
       // There is no point saving disabled blocks. Still, we need to save them
-      // beecause the 'title' attribute is saved to the {blocks} table.
+      // because the 'title' attribute is saved to the {blocks} table.
       if (isset($block['bid'])) {
         // If the block has a bid property, it comes from the database and
         // the record needs to be updated, so set the primary key to 'bid'
@@ -833,6 +838,15 @@ function _block_get_cache_id($block) {
  * Implements hook_flush_caches().
  */
 function block_flush_caches() {
+  if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'install') {
+    // Rehash blocks for active themes. We don't use list_themes() here,
+    // because if MAINTENANCE_MODE is defined it skips reading the database,
+    // and we can't tell which themes are active.
+    $themes = db_query("SELECT name FROM {system} WHERE type = 'theme' AND status = 1");
+    foreach($themes as $theme) {
+      _block_rehash($theme->name);
+    }
+  }
   return array('cache_block');
 }
 
Index: modules/block/block.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.test,v
retrieving revision 1.52
diff -u -p -r1.52 block.test
--- modules/block/block.test	26 Apr 2010 14:10:40 -0000	1.52
+++ modules/block/block.test	24 May 2010 02:49:09 -0000
@@ -261,6 +261,27 @@ class BlockTestCase extends DrupalWebTes
     ));
     $this->assertFieldByXPath($xpath, FALSE, t('Custom block found in %region_name region.', array('%region_name' => $region['name'])));
   }
+
+  /**
+   * Test _block_rehash().
+   */
+  function testBlockRehash() {
+    module_enable(array('block_test'));
+    $this->assertTrue(module_exists('block_test'), t('Test block module enabled.'));
+    _block_rehash();
+
+    // Our test block's caching should default to DRUPAL_CACHE_PER_ROLE.
+    $current_caching = db_query("SELECT cache FROM {block} WHERE module = 'block_test' AND delta = 'test_cache'")->fetchField();
+    $this->assertEqual($current_caching, DRUPAL_CACHE_PER_ROLE, t('Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.'));
+
+    // Disable caching for this block.
+    variable_set('block_test_caching', DRUPAL_NO_CACHE);
+    _block_rehash();
+
+    // Verify that changing the caching mode affected the database.
+    $current_caching = db_query("SELECT cache FROM {block} WHERE module = 'block_test' AND delta = 'test_cache'")->fetchField();
+    $this->assertEqual($current_caching, DRUPAL_NO_CACHE, t("Test block's database entry updated to DRUPAL_NO_CACHE."));
+  }
 }
 
 class NonDefaultBlockAdmin extends DrupalWebTestCase {
Index: modules/block/tests/block_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/tests/block_test.module,v
retrieving revision 1.2
diff -u -p -r1.2 block_test.module
--- modules/block/tests/block_test.module	26 Apr 2010 14:10:40 -0000	1.2
+++ modules/block/tests/block_test.module	24 May 2010 02:49:09 -0000
@@ -12,6 +12,7 @@
 function block_test_block_info() {
   $blocks['test_cache'] = array(
     'info' => t('Test block caching'),
+    'cache' => variable_get('block_test_caching', DRUPAL_CACHE_PER_ROLE),
   );
 
   $blocks['test_html_id'] = array(
