List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:January 30 2009 1:29am
Subject:bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2988)
Bug#41227
View as plain text  
#At file:///G:/bzr/mysql-6.0-falcon-team/ based on revid:hky@stripped

 2988 Vladislav Vaintroub	2009-01-30
      Bug#41227  Falcon: potential corruption of RecordLocatorPage 
      on recovery
      
      Problem: If falcon pager size is set to 32K, recovery 
      involving blob updates will crash in assertion. 
      
      Section::redoBlobUpdate and Section::redoBlobDelete will
      try to set available space to the page size (32K)in record locator page
      However, 32K=32768  becomes negative (-32768) when converted to short.
      RecordLocatorPage::linkSpaceSlot() checks for positive value for 
      "space available" and asserts.
      
      Fix is to set spaceAvailable to more realistic value 
      (page size - page header overhead) that is guaranteed not to overflow 
      and not to change sign of a short even for 32 K pages.
modified:
  storage/falcon/DataPage.h
  storage/falcon/RecordLocatorPage.cpp
  storage/falcon/Section.cpp

=== modified file 'storage/falcon/DataPage.h'
--- a/storage/falcon/DataPage.h	2008-09-27 18:37:54 +0000
+++ b/storage/falcon/DataPage.h	2009-01-30 01:28:53 +0000
@@ -61,4 +61,7 @@ public:
 	LineIndex	lineIndex [1];
 };
 
+/* Maximal length of data that can be stored in a page */
+#define DATA_PAGE_MAX_AVAILABLE_SPACE(pageSize) (pageSize - sizeof(DataPage))
+
 #endif // !defined(AFX_DATAPAGE_H__6A019C29_A340_11D2_AB5A_0000C01D2301__INCLUDED_)

=== modified file 'storage/falcon/RecordLocatorPage.cpp'
--- a/storage/falcon/RecordLocatorPage.cpp	2008-06-17 17:41:54 +0000
+++ b/storage/falcon/RecordLocatorPage.cpp	2009-01-30 01:28:53 +0000
@@ -269,7 +269,9 @@ void RecordLocatorPage::printPage(void)
 
 void RecordLocatorPage::setIndexSlot(int slot, int32 pageNumber, int line, int availableSpace)
 {
-	ASSERT(availableSpace >= 0);
+	// Check that availableSpace is positive and can be converted to short
+	// without losing bits or changing sign
+	ASSERT(availableSpace >= 0 && availableSpace < 0x8000); 
 	
 	RecordIndex *element = elements + slot;
 	//validateSpaceSlots();
@@ -366,6 +368,7 @@ void RecordLocatorPage::setIndexSlot(int
 
 void RecordLocatorPage::insertSpaceSlot(int slot, int availableSpace)
 {
+	ASSERT(availableSpace > 0 && availableSpace < 0x8000); 
 	int priorSlot;
 	int nextSlot;
 	

=== modified file 'storage/falcon/Section.cpp'
--- a/storage/falcon/Section.cpp	2009-01-29 14:14:02 +0000
+++ b/storage/falcon/Section.cpp	2009-01-30 01:28:53 +0000
@@ -1437,7 +1437,7 @@ void Section::redoBlobUpdate(Dbb* dbb, i
 	if (page->maxLine <= locatorLine)
 		page->maxLine = locatorLine + 1;
 
-	page->setIndexSlot(locatorLine, dataPage, dataLine, dbb->pageSize);
+	page->setIndexSlot(locatorLine, dataPage, dataLine, DATA_PAGE_MAX_AVAILABLE_SPACE(dbb->pageSize));
 	bdb->release(REL_HISTORY);
 }
 
@@ -1471,7 +1471,7 @@ void Section::redoBlobDelete(Dbb* dbb, i
 	BDB_HISTORY(bdb);
 	bdb->mark(NO_TRANSACTION);
 	RecordLocatorPage *page = (RecordLocatorPage*) bdb->buffer;
-	page->setIndexSlot(locatorLine, 0, 0, dbb->pageSize);
+	page->setIndexSlot(locatorLine, 0, 0, DATA_PAGE_MAX_AVAILABLE_SPACE(dbb->pageSize));
 	bdb->release(REL_HISTORY);
 }
 

Thread
bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2988)Bug#41227Vladislav Vaintroub30 Jan