[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/at45db LogStorageP.nc,
1.1.2.9, 1.1.2.10
David Gay
idgay at users.sourceforge.net
Thu Jun 1 09:35:55 PDT 2006
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv6503
Modified Files:
Tag: tinyos-2_0_devel-BRANCH
LogStorageP.nc
Log Message:
better log storage implementation
Index: LogStorageP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/LogStorageP.nc,v
retrieving revision 1.1.2.9
retrieving revision 1.1.2.10
diff -C2 -d -r1.1.2.9 -r1.1.2.10
*** LogStorageP.nc 31 May 2006 23:34:45 -0000 1.1.2.9
--- LogStorageP.nc 1 Jun 2006 16:35:53 -0000 1.1.2.10
***************
*** 143,149 ****
void readFromBeginning() {
! /* Set position to end of page before first page, to force page advance
! on next read */
! s[client].rpos = 0;
s[client].rpage = firstVolumePage() - 1;
s[client].rend = s[client].roffset = 0;
--- 143,149 ----
void readFromBeginning() {
! /* Set position to page before first page and force advance to next
! page on next read */
! s[client].rpos = SEEK_BEGINNING;
s[client].rpage = firstVolumePage() - 1;
s[client].rend = s[client].roffset = 0;
***************
*** 168,176 ****
}
! void emptyLog() {
! s[client].positionKnown = TRUE;
! s[client].wpos = 0;
! setWritePage(firstVolumePage());
! readFromBeginning();
}
--- 168,177 ----
}
! void wmetadataStart();
!
! void sync() {
! metadata.flags = F_SYNC | F_LASTVALID;
! metadata.lastRecordOffset = s[client].woffset;
! wmetadataStart();
}
***************
*** 185,189 ****
void locateStart();
void rmetadataStart();
- void wmetadataStart();
void seekStart();
--- 186,189 ----
***************
*** 259,263 ****
command error_t LinearWrite.append[logstorage_t id](void* buf, storage_len_t length) {
! return newRequest(R_APPEND, id, FALSE, buf, length);
}
--- 259,272 ----
command error_t LinearWrite.append[logstorage_t id](void* buf, storage_len_t length) {
! if (len > call LinearRead.getSize[id]() - PAGE_SIZE)
! /* Writes greater than the volume size are invalid.
! Writes equal to the volume size could break the log volume
! invariant (see next comment).
! Writes that span the whole volume could lead to problems
! at boot time (no valid block with a record boundary).
! Refuse them all. */
! return EINVAL;
! else
! return newRequest(R_APPEND, id, FALSE, buf, length);
}
***************
*** 286,295 ****
}
! command storage_cookie_t LinearRead.getSize[logstorage_t id]() {
! return call At45dbVolume.volumeSize[id]() * PAGE_SIZE;
}
command error_t CircularWrite.append[logstorage_t id](void* buf, storage_len_t length) {
! return newRequest(R_APPEND, id, TRUE, buf, length);
}
--- 295,313 ----
}
! command storage_len_t LinearRead.getSize[logstorage_t id]() {
! return call At45dbVolume.volumeSize[id]() * (storage_len_t)PAGE_SIZE;
}
command error_t CircularWrite.append[logstorage_t id](void* buf, storage_len_t length) {
! if (len > call CircularRead.getSize[id]() - PAGE_SIZE)
! /* Writes greater than the volume size are invalid.
! Writes equal to the volume size could break the log volume
! invariant (see next comment).
! Writes that span the whole volume could lead to problems
! at boot time (no valid block with a record boundary).
! Refuse them all. */
! return EINVAL;
! else
! return newRequest(R_APPEND, id, TRUE, buf, length);
}
***************
*** 318,322 ****
}
! command storage_cookie_t CircularRead.getSize[logstorage_t id]() {
return call LinearRead.getSize[id]();
}
--- 336,340 ----
}
! command storage_len_t CircularRead.getSize[logstorage_t id]() {
return call LinearRead.getSize[id]();
}
***************
*** 327,354 ****
void eraseMetadataDone() {
! emptyLog(); // reset write pointer
endRequest(SUCCESS);
}
! void eraseContinue() {
! /* We erase backwards. That leaves the first two pages in the cache */
! if (lastPage == firstPage)
{
! emptyLog();
! /* If we just reboot after erasing the flash, then the next attempt
! to locate log boundaries will have to scan the while flash
! (looking for a valid block). To reduce the chances of this, we
! write a valid header in block 0 after erase. */
! metadata.flags = 0;
wmetadataStart();
}
else
! call At45db.erase(--lastPage, AT45_ERASE);
}
void eraseStart() {
firstPage = firstVolumePage();
lastPage = lastVolumePage();
! eraseContinue();
}
--- 345,376 ----
void eraseMetadataDone() {
! s[client].positionKnown = TRUE;
! s[client].wpos = PAGE_SIZE; // last page has offset 0 and is before us
! s[client].circled = FALSE;
! setWritePage(firstVolumePage());
! readFromBeginning();
!
endRequest(SUCCESS);
}
! void eraseEraseDone() {
! if (firstPage == lastPage - 1)
{
! /* We create a valid, synced last page */
! metadata.flags = F_SYNC | F_LASTVALID;
! metadata.lastRecordOffset = 0;
! setWritePage(firstPage);
! s[client].wpos = 0;
wmetadataStart();
}
else
! call At45db.erase(firstPage++, AT45_ERASE);
}
void eraseStart() {
+ s[client].positionKnown = FALSE; // in case erase fails
firstPage = firstVolumePage();
lastPage = lastVolumePage();
! eraseEraseDone();
}
***************
*** 359,406 ****
void locateLastRecord();
- at45page_t locateCurrentPage() {
- return firstPage + ((lastPage - firstPage) >> 1);
- }
-
void locateLastCrcDone(uint16_t crc) {
! if (crc == metadata.crc)
{
! /* We've found the last valid page with a record-end */
! s[client].positionKnown = TRUE;
! if (metadata.flags & F_SYNC) /* must start on next page */
! {
! setWritePage(firstPage + 1);
! s[client].wpos = metadata.pos + PAGE_SIZE;
! }
! else
! {
! s[client].wpage = firstPage;
! s[client].woffset = metadata.lastRecordOffset;
! s[client].wpos = metadata.pos + metadata.lastRecordOffset;
! }
! /* If we're on the first pass (no F_CIRCLED flag), the read
! pointer starts at the beginning of the flash. Otherwise,
! we invalidate it, which will force read requests to find
! the first valid page after the current write pointer. */
! s[client].circled = (metadata.flags & F_CIRCLED) != 0;
! if (s[client].circled)
! {
! if (!s[client].circular) // oops
! {
! /* Maybe treating the log as empty would be better? */
! endRequest(FAIL);
! return;
! }
! invalidateReadPointer();
}
- else
- readFromBeginning();
! startRequest();
}
else
! locateLastRecord();
}
--- 381,427 ----
void locateLastRecord();
void locateLastCrcDone(uint16_t crc) {
! if (crc != metadata.crc)
{
! locateLastRecord();
! return;
! }
! /* We've found the last valid page with a record-end. Set up
! the read and write positions. */
! if (metadata.flags & F_SYNC) /* must start on next page */
! {
! setWritePage(firstPage + 1);
! s[client].wpos = metadata.pos + PAGE_SIZE;
! }
! else
! {
! s[client].wpage = firstPage;
! s[client].woffset = metadata.lastRecordOffset;
! s[client].wpos = metadata.pos + metadata.lastRecordOffset;
! }
!
! /* If we're on the first pass (no F_CIRCLED flag), the read
! pointer starts at the beginning of the flash. Otherwise,
! we invalidate it, which will force read requests to find
! the first valid page after the current write pointer. */
! s[client].circled = (metadata.flags & F_CIRCLED) != 0;
! if (s[client].circled)
! {
! if (!s[client].circular) // oops
! {
! endRequest(FAIL);
! return;
}
! invalidateReadPointer();
}
else
! readFromBeginning();
!
! /* And we can now proceed to the real request */
! s[client].positionKnown = TRUE;
! startRequest();
}
***************
*** 413,424 ****
void locateLastRecord() {
! if (firstPage == firstVolumePage())
{
! /* There were no valid pages with a record end */
! emptyLog();
! startRequest();
}
else
! readMetadata(--firstPage);
}
--- 434,451 ----
void locateLastRecord() {
! if (firstPage == lastPage)
{
! /* We walked all the way back to the last page, and it's not
! valid. The log-volume invariant is not holding. Fail out. */
! endRequest(FAIL);
! return;
}
+
+ if (firstPage == firstVolumePage())
+ firstPage = lastPage;
else
! firstPage--;
!
! readMetadata(firstPage);
}
***************
*** 427,433 ****
--- 454,465 ----
/* firstPage is one after last valid page, but the last page with
a record end may be some pages earlier. Search for it. */
+ lastPage = lastVolumePage() - 1;
locateLastRecord();
}
+ at45page_t locateCurrentPage() {
+ return firstPage + ((lastPage - firstPage) >> 1);
+ }
+
void locateBinarySearch() {
if (lastPage <= firstPage)
***************
*** 465,493 ****
void locateFirstCrcDone(uint16_t crc) {
- firstPage++;
if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)
! {
! metaState = META_LOCATE;
! /* We track the page with the largest position found. */
! s[client].wpos = metadata.pos;
! /* We now know that the valid pages span a contiguous sequence
! starting at firstPage - 1. The binary search will look for
! the page with the largest position. */
! locateBinarySearch();
! }
! else if (firstPage != lastPage)
! /* Try the next page. There can be an arbitrary number of
! consecutive bad pages (see discussion at start of this file) */
! readMetadata(firstPage);
else
! {
! /* Found no valid page. We might want to give up after some
! bounded number of pages, rather than checking the whole
! log -- many bad consecutive pages is extremely unlikely and
! probably indicates a major problem somewhere. */
! emptyLog();
! startRequest();
! }
!
}
--- 497,507 ----
void locateFirstCrcDone(uint16_t crc) {
if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)
! s[client].wpos = metadata.pos;
else
! s[client].wpos = 0;
!
! metaState = META_LOCATE;
! locateBinarySearch();
}
***************
*** 500,505 ****
metaState = META_LOCATEFIRST;
firstPage = firstVolumePage();
! lastPage = lastVolumePage();
! readMetadata(firstPage);
}
--- 514,519 ----
metaState = META_LOCATEFIRST;
firstPage = firstVolumePage();
! lastPage = lastVolumePage() - 1;
! readMetadata(lastPage);
}
***************
*** 551,559 ****
void appendStart() {
! /* Set lastRecordOffset in case we need to write metadata (see
! wmetadataStart) */
! metadata.lastRecordOffset = s[client].woffset;
! metadata.flags = F_LASTVALID;
! appendContinue();
}
--- 565,588 ----
void appendStart() {
! storage_len_t vlen = (storage_len_t)npages() * PAGE_SIZE;
!
! /* If request would span the end of the flash, sync, to maintain the
! invariant that the last flash page is synced and that either
! the first or last pages are valid.
!
! Note that >= in the if below means we won't write a record that
! would end on the last byte of the last page, as this would mean that
! we would not sync the last page, breaking the log volume
! invariant */
! if (s[client].wpos % vlen >= vlen - len)
! sync();
! else
! {
! /* Set lastRecordOffset in case we need to write metadata (see
! wmetadataStart) */
! metadata.lastRecordOffset = s[client].woffset;
! metadata.flags = F_LASTVALID;
! appendContinue();
! }
}
***************
*** 566,574 ****
endRequest(SUCCESS);
else
! {
! metadata.flags = F_SYNC | F_LASTVALID;
! metadata.lastRecordOffset = s[client].woffset;
! wmetadataStart();
! }
}
--- 595,599 ----
endRequest(SUCCESS);
else
! sync();
}
***************
*** 622,626 ****
void wmetadataWriteDone() {
metaState = META_IDLE;
! if (s[client].request == R_SYNC)
call At45db.sync(firstPage);
else
--- 647,651 ----
void wmetadataWriteDone() {
metaState = META_IDLE;
! if (metadata.flags & F_SYNC)
call At45db.sync(firstPage);
else
***************
*** 700,716 ****
firstPage = firstVolumePage();
if (firstPage == s[client].wpage)
! {
! if (!s[client].rvalid)
! /* We cannot find a record boundary to start at (we've just
! walked through the whole log...). Give up. */
! endRequest(SUCCESS);
! else
! {
! /* The current write page has no metadata yet, so we fake it */
! metadata.flags = 0;
! metadata.pos = s[client].wpos - s[client].woffset;
! continueReadAt(0);
! }
! }
else
readMetadata(firstPage);
--- 725,739 ----
firstPage = firstVolumePage();
if (firstPage == s[client].wpage)
! if (!s[client].rvalid)
! /* We cannot find a record boundary to start at (we've just
! walked through the whole log...). Give up. */
! endRequest(SUCCESS);
! else
! {
! /* The current write page has no metadata yet, so we fake it */
! metadata.flags = 0;
! metadata.pos = s[client].wpos - s[client].woffset;
! continueReadAt(0);
! }
else
readMetadata(firstPage);
***************
*** 768,772 ****
invalidateReadPointer(); // default to beginning of log
! if (offset > s[client].wpos)
{
endRequest(EINVAL);
--- 791,800 ----
invalidateReadPointer(); // default to beginning of log
! /* The write positions are offset by PAGE_SIZE (see emptyLog) */
!
! if (offset == SEEK_BEGINNING)
! offset = PAGE_SIZE;
!
! if (offset > s[client].wpos || offset < PAGE_SIZE)
{
endRequest(EINVAL);
***************
*** 778,783 ****
page's metadata.pos field matches the cookie's value */
s[client].rpos = offset;
! s[client].roffset = offset % PAGE_SIZE;
! s[client].rpage = firstVolumePage() + (offset / PAGE_SIZE) % npages();
s[client].rend = PAGE_SIZE; // default to no sync flag
--- 806,811 ----
page's metadata.pos field matches the cookie's value */
s[client].rpos = offset;
! s[client].roffset = (offset - PAGE_SIZE) % PAGE_SIZE;
! s[client].rpage = firstVolumePage() + ((offset - PAGE_SIZE) / PAGE_SIZE) % npages();
s[client].rend = PAGE_SIZE; // default to no sync flag
***************
*** 809,813 ****
endRequest(FAIL);
else
! eraseContinue();
}
--- 837,841 ----
endRequest(FAIL);
else
! eraseEraseDone();
}
***************
*** 828,833 ****
if (error != SUCCESS)
endRequest(FAIL);
! else
! syncMetadataDone();
}
--- 856,865 ----
if (error != SUCCESS)
endRequest(FAIL);
! else switch (s[client].request)
! {
! case R_ERASE: eraseMetadataDone(); break;
! case R_APPEND: appendStart(); break;
! case R_SYNC: syncMetadataDone(); break;
! }
}
***************
*** 836,841 ****
if (error != SUCCESS)
endRequest(FAIL);
- else if (s[client].request == R_ERASE)
- eraseMetadataDone();
else
appendMetadataDone();
--- 868,871 ----
More information about the Tinyos-2-commits
mailing list