From 523f4aa9fd31317565640318165dac728bb45e58 Mon Sep 17 00:00:00 2001
From: marko <Unknown>
Date: Tue, 27 Jan 2009 08:05:24 +0000
Subject: [PATCH] branches/zip: buf_LRU_invalidate_tablespace(): Fix a race
 condition: read zip_size while still holding block_mutex.

---
 ChangeLog     |  9 +++++++++
 buf/buf0lru.c | 12 +++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e6aafa3104..63b42f9d6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-01-27	The InnoDB Team
+
+	* buf/buf0lru.c:
+	Fix a race condition in buf_LRU_invalidate_tablespace():
+	The compressed page size (zip_size) was read while the block
+	descriptor was no longer protected by a mutex.  This could lead to
+	corruption when a table is dropped on a busy system that contains
+	compressed tables.
+
 2009-01-26	The InnoDB Team
 
 	* include/buf0buf.h, include/buf0buf.ic, buf/buf0buf.c,
diff --git a/buf/buf0lru.c b/buf/buf0lru.c
index 3295ce85f0..846a737dd5 100644
--- a/buf/buf0lru.c
+++ b/buf/buf0lru.c
@@ -300,7 +300,6 @@ buf_LRU_invalidate_tablespace(
 	ulint	id)	/* in: space id */
 {
 	buf_page_t*	bpage;
-	ulint		page_no;
 	ibool		all_freed;
 
 	/* Before we attempt to drop pages one by one we first
@@ -351,18 +350,21 @@ scan_again:
 #endif
 			if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE
 			    && ((buf_block_t*) bpage)->is_hashed) {
-				page_no = buf_page_get_page_no(bpage);
+				ulint	page_no;
+				ulint	zip_size;
 
 				buf_pool_mutex_exit();
+
+				zip_size = buf_page_get_zip_size(bpage);
+				page_no = buf_page_get_page_no(bpage);
+
 				mutex_exit(block_mutex);
 
 				/* Note that the following call will acquire
 				an S-latch on the page */
 
 				btr_search_drop_page_hash_when_freed(
-					id,
-					buf_page_get_zip_size(bpage),
-					page_no);
+					id, zip_size, page_no);
 				goto scan_again;
 			}
 
-- 
2.30.9