From: Frazer Clement Date: August 27 2008 3:19pm Subject: bzr commit into mysql-5.1 tree (frazer:2667) Bug#39037 List-Archive: http://lists.mysql.com/commits/52742 X-Bug: 39037 Message-Id: <200808271519.m7RFJK6b015804@forth.ndb.mysql.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0160157140==" --===============0160157140== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/frazer/bzr/mysql-5.1-telco-6.2-bugs/ ------------------------------------------------------------ revno: 2667 revision-id: frazer@stripped parent: frazer@stripped committer: Frazer Clement branch nick: mysql-5.1-telco-6.2-bugs timestamp: Wed 2008-08-27 16:19:05 +0100 message: Bug#39037 Segment linking bug Modify import() to ensure nextSegment ptr set when importing Add assert-only linked segment integrity check modified: storage/ndb/src/kernel/vm/LongSignal.hpp sp1f-longsignal.hpp-20040414082422-zttdipy55hdqoxdh4ubjdgn4lydokjyq storage/ndb/src/kernel/vm/TransporterCallback.cpp sp1f-transportercallback.-20040414082423-orvgt4lovbdsqu5gjdkhc6oefovmavrk per-file comments: storage/ndb/src/kernel/vm/LongSignal.hpp Add new linked-segment integrity check function storage/ndb/src/kernel/vm/TransporterCallback.cpp Fix import(). Add integrity check method --===============0160157140== MIME-Version: 1.0 Content-Type: text/text/x-diff; charset="us-ascii"; name="patch-2667.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline === modified file 'storage/ndb/src/kernel/vm/LongSignal.hpp' --- a/storage/ndb/src/kernel/vm/LongSignal.hpp 2006-12-23 19:20:40 +0000 +++ b/storage/ndb/src/kernel/vm/LongSignal.hpp 2008-08-27 15:19:05 +0000 @@ -61,6 +61,9 @@ void getSections(Uint32 secCount, SegmentedSectionPtr ptr[3]); void releaseSections(Uint32 secCount, SegmentedSectionPtr ptr[3]); +/* Internal verification */ +bool verifySection(Uint32 firstIVal, + SectionSegmentPool& thePool= g_sectionSegmentPool); #include "DataBuffer.hpp" === modified file 'storage/ndb/src/kernel/vm/TransporterCallback.cpp' --- a/storage/ndb/src/kernel/vm/TransporterCallback.cpp 2006-12-23 19:20:40 +0000 +++ b/storage/ndb/src/kernel/vm/TransporterCallback.cpp 2008-08-27 15:19:05 +0000 @@ -60,13 +60,72 @@ return connectionError[i].text; } + +/** + * verifySection + * Assertion method to check that a segmented section is constructed + * 'properly' where 'properly' is loosly defined. + */ +bool +verifySection(Uint32 firstIVal, SectionSegmentPool& thePool) +{ + if (firstIVal == RNIL) + return true; + + /* Get first section ptr (With assertions in getPtr) */ + SectionSegment* first= thePool.getPtr(firstIVal); + + assert(first != NULL); + Uint32 totalSize= first->m_sz; + Uint32 lastSegIVal= first->m_lastSegment; + + /* Hmm, need to be careful of length == 0 + * Nature abhors a segmented section with length 0 + */ + //assert(totalSize != 0); + assert(lastSegIVal != RNIL); /* Should never be == RNIL */ + /* We ignore m_ownerRef */ + + if (totalSize <= SectionSegment::DataLength) + { + /* 1 segment */ + assert(first->m_lastSegment == firstIVal); + // m_nextSegment not always set to RNIL on last segment + //assert(first->m_nextSegment == RNIL); + } + else + { + /* > 1 segment */ + assert(first->m_nextSegment != RNIL); + assert(first->m_lastSegment != firstIVal); + Uint32 currIVal= firstIVal; + SectionSegment* curr= first; + + /* Traverse segments to where we think the end should be */ + while (totalSize > SectionSegment::DataLength) + { + currIVal= curr->m_nextSegment; + curr= thePool.getPtr(currIVal); + totalSize-= SectionSegment::DataLength; + /* Ignore m_ownerRef, m_sz, m_lastSegment of intermediate + * Segments + */ + } + + /* Once we are here, we are on the last Segment of this Section + * Check that last segment is as stated in the first segment + */ + assert(currIVal == lastSegIVal); + // m_nextSegment not always set properly on last segment + //assert(curr->m_nextSegment == RNIL); + /* Ignore m_ownerRef, m_sz, m_lastSegment of last segment */ + } + + return true; +} + bool import(Ptr & first, const Uint32 * src, Uint32 len){ - /** - * Dummy data used when setting prev.m_nextSegment for first segment of a - * section - */ - Uint32 dummyPrev[4]; first.p = 0; if(g_sectionSegmentPool.seize(first)){ @@ -78,16 +137,15 @@ first.p->m_sz = len; first.p->m_ownerRef = 0; - Ptr prevPtr = { (SectionSegment *)&dummyPrev[0], 0 }; Ptr currPtr = first; while(len > SectionSegment::DataLength){ - prevPtr.p->m_nextSegment = currPtr.i; memcpy(&currPtr.p->theData[0], src, 4 * SectionSegment::DataLength); src += SectionSegment::DataLength; len -= SectionSegment::DataLength; - prevPtr = currPtr; + Ptr prevPtr = currPtr; if(g_sectionSegmentPool.seize(currPtr)){ + prevPtr.p->m_nextSegment = currPtr.i; ; } else { first.p->m_lastSegment = prevPtr.i; @@ -98,6 +156,8 @@ first.p->m_lastSegment = currPtr.i; currPtr.p->m_nextSegment = RNIL; memcpy(&currPtr.p->theData[0], src, 4 * len); + + assert(verifySection(first.i)); return true; } @@ -117,6 +177,8 @@ headPtr.p->m_sz += tailPtr.p->m_sz; oldTailPtr.p->m_nextSegment = tailPtr.i; + + assert(verifySection(head)); } void @@ -125,6 +187,8 @@ Uint32 len = _ptr.sz; SectionSegment * ptrP = _ptr.p; + + assert(verifySection(_ptr.i, thePool)); while(len > 60){ memcpy(insertPtr, &ptrP->theData[0], 4 * 60); @@ -180,6 +244,7 @@ void release(SegmentedSectionPtr & ptr){ + assert(verifySection(ptr.i)); g_sectionSegmentPool.releaseList(relSz(ptr.sz), ptr.i, ptr.p->m_lastSegment); --===============0160157140==--